void CBeam::RelinkBeam( void )
{
	// FIXME: Why doesn't this just define the absbox too?
	// It seems that we don't need to recompute the absbox
	// in CBaseEntity::SetObjectCollisionBox, in fact the absbox
	// computed there seems way too big
	Vector startPos = GetAbsStartPos(), endPos = GetAbsEndPos();

	Vector vecAbsExtra1, vecAbsExtra2;
	bool bUseExtraPoints = false;

#ifdef PORTAL
	CBaseEntity *pStartEntity = GetStartEntityPtr();
	
	CTraceFilterSkipClassname traceFilter( pStartEntity, "prop_energy_ball", COLLISION_GROUP_NONE );
	
	ITraceFilter *pEntityBeamTraceFilter = NULL;
	if ( pStartEntity )
		pEntityBeamTraceFilter = pStartEntity->GetBeamTraceFilter();

	CTraceFilterChain traceFilterChain( &traceFilter, pEntityBeamTraceFilter );

	bUseExtraPoints = UTIL_Portal_Trace_Beam( this, startPos, endPos, vecAbsExtra1, vecAbsExtra2, &traceFilterChain );
#endif

	// UNDONE: Should we do this to make the boxes smaller?
	//SetAbsOrigin( startPos );

	Vector vecBeamMin, vecBeamMax;
	VectorMin( startPos, endPos, vecBeamMin );
	VectorMax( startPos, endPos, vecBeamMax );

	if ( bUseExtraPoints )
	{
		VectorMin( vecBeamMin, vecAbsExtra1, vecBeamMin );
		VectorMin( vecBeamMin, vecAbsExtra2, vecBeamMin );
		VectorMax( vecBeamMax, vecAbsExtra1, vecBeamMax );
		VectorMax( vecBeamMax, vecAbsExtra2, vecBeamMax );
	}

	SetCollisionBounds( vecBeamMin - GetAbsOrigin(), vecBeamMax - GetAbsOrigin() );
}
示例#2
0
CBaseHandle CTFGameMovement::TestPlayerPosition( const Vector& pos, int collisionGroup, trace_t& pm )
{
	if( tf_solidobjects.GetBool() == false )
		return BaseClass::TestPlayerPosition( pos, collisionGroup, pm );

	Ray_t ray;
	ray.Init( pos, pos, GetPlayerMins(), GetPlayerMaxs() );
	
	CTraceFilterObject traceFilter( mv->m_nPlayerHandle.Get(), collisionGroup );
	enginetrace->TraceRay( ray, PlayerSolidMask(), &traceFilter, &pm );

	if ( (pm.contents & PlayerSolidMask()) && pm.m_pEnt )
	{
		return pm.m_pEnt->GetRefEHandle();
	}
	else
	{	
		return INVALID_EHANDLE_INDEX;
	}
}
const Vector CSDKPlayer::CalculateThirdPersonCameraPosition(const Vector& vecEye, const QAngle& angCamera)
{
	float flCamBackIdle = GetUserInfoFloat("da_cam_back");
	float flCamUpIdle = GetUserInfoFloat("da_cam_up");
	float flCamRightIdle = GetUserInfoFloat("da_cam_right");

	float flCamBackAim = GetUserInfoFloat("da_cam_back_aim");
	float flCamUpAim = GetUserInfoFloat("da_cam_up_aim");
	float flCamRightAim = GetUserInfoFloat("da_cam_right_aim");

	float flCamBack = RemapValClamped(Gain(m_Shared.GetAimIn(), 0.8f), 0, 1, flCamBackIdle, flCamBackAim);
	float flCamUp = RemapValClamped(Gain(m_Shared.GetAimIn(), 0.8f), 0, 1, flCamUpIdle, flCamUpAim);
	float flCamRight = RemapValClamped(Gain(m_Shared.GetAimIn(), 0.8f), 0, 1, flCamRightIdle, flCamRightAim);

	m_flSideLerp = Approach(m_bThirdPersonCamSide?1:-1, m_flSideLerp, gpGlobals->frametime*15);
	flCamRight *= m_flSideLerp;

	Vector camForward, camRight, camUp;
	AngleVectors( angCamera, &camForward, &camRight, &camUp );

	Vector vecCameraOffset = -camForward*flCamBack + camRight*flCamRight + camUp*flCamUp;

	m_flStuntLerp = Approach((m_Shared.IsDiving()||m_Shared.IsRolling())?1:0, m_flStuntLerp, gpGlobals->frametime*2);

	if (m_flStuntLerp)
		vecCameraOffset += camUp * (m_flStuntLerp * da_cam_stunt_up.GetFloat());

	Vector vecNewOrigin = vecEye + vecCameraOffset;

	trace_t trace;

	CTraceFilterSimple traceFilter( this, COLLISION_GROUP_NONE );
	UTIL_TraceHull( vecEye, vecNewOrigin,
		Vector(-CAM_HULL_OFFSET, -CAM_HULL_OFFSET, -CAM_HULL_OFFSET), Vector(CAM_HULL_OFFSET, CAM_HULL_OFFSET, CAM_HULL_OFFSET),
		MASK_VISIBLE|CONTENTS_GRATE, &traceFilter, &trace );

	m_flCameraLerp = Approach(trace.fraction, m_flCameraLerp, da_cambacklerp.GetFloat()*gpGlobals->frametime);

	return vecEye + vecCameraOffset * m_flCameraLerp;
}
示例#4
0
CBaseEntity *CDecal::GetDecalEntityAndPosition( Vector *pPosition, bool bStatic )
{
	CBaseEntity *pEntity = NULL;
	if ( !m_entityName )
	{
		trace_t trace;
		Vector start = GetAbsOrigin();
		Vector direction(1,1,1);
		if ( GetAbsAngles() == vec3_angle )
		{
			start -= direction * 5;
		}
		else
		{
			GetVectors( &direction, NULL, NULL );
		}
		Vector end = start + direction * 10;
		if ( bStatic )
		{
			CTraceFilterValidForDecal traceFilter( this, COLLISION_GROUP_NONE );
			UTIL_TraceLine( start, end, MASK_SOLID, &traceFilter, &trace );
		}
		else
		{
			UTIL_TraceLine( start, end, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trace );
		}
		if ( trace.DidHitNonWorldEntity() )
		{
			*pPosition = trace.endpos;
			return trace.m_pEnt;
		}
	}
	else
	{
		pEntity = gEntList.FindEntityByName( NULL, m_entityName );
	}

	*pPosition = GetAbsOrigin();
	return pEntity;
}
//-----------------------------------------------------------------------------
// Purpose: Check the weapon LOS for an owner at an arbitrary position
//			If bSetConditions is true, LOS related conditions will also be set
//-----------------------------------------------------------------------------
bool CASW_Weapon::WeaponLOSCondition( const Vector &ownerPos, const Vector &targetPos, bool bSetConditions )
{
	bool bHasLOS = BaseClass::WeaponLOSCondition(ownerPos, targetPos, bSetConditions);

	// if the weapon has LOS, then do another wider trace to check we don't hit any friendlies
	//   this is to stop the AI marines shooting way too close to other marines, which stops the player thinking about positioning so much
	if (bHasLOS && GetOwner() && asw_weapon_safety_hull.GetFloat() > 0)
	{
		CAI_BaseNPC* npcOwner = GetOwner()->MyNPCPointer();	
		Vector vecRelativeShootPosition;
		VectorSubtract( npcOwner->Weapon_ShootPosition(), npcOwner->GetAbsOrigin(), vecRelativeShootPosition );	// Find its relative shoot position
		Vector barrelPos = ownerPos + vecRelativeShootPosition;	
		CASWWeaponLOSFilter traceFilter( GetOwner(), npcOwner->GetEnemy(), COLLISION_GROUP_BREAKABLE_GLASS );	// Use the custom LOS trace filter
		trace_t tr;
		UTIL_TraceHull( barrelPos, targetPos, Vector(-asw_weapon_safety_hull.GetFloat(), -asw_weapon_safety_hull.GetFloat(), -asw_weapon_safety_hull.GetFloat()),
						Vector(asw_weapon_safety_hull.GetFloat(), asw_weapon_safety_hull.GetFloat(), asw_weapon_safety_hull.GetFloat()),	MASK_SHOT, &traceFilter, &tr );

		if ( tr.fraction == 1.0 || tr.m_pEnt == npcOwner->GetEnemy() )	
			return true;

		// if a friendly is in the way, then we report failure
		CBaseCombatCharacter *pBCC = ToBaseCombatCharacter( tr.m_pEnt );
		if ( pBCC ) 
		{
			if ( npcOwner->IRelationType( pBCC ) == D_HT )
				return true;

			if ( bSetConditions )
			{
				npcOwner->SetCondition( COND_WEAPON_BLOCKED_BY_FRIEND );
			}
			return false;
		}
	}

	return bHasLOS;
}
示例#6
0
CBaseHandle CHL2WarsGameMovement::TestPlayerPosition( const Vector& pos, int collisionGroup, trace_t& pm )
{
	if( player->GetMoveType() != MOVETYPE_STRATEGIC )
	{
		return CGameMovement::TestPlayerPosition( pos, collisionGroup, pm );
	}


	Ray_t ray;
	ray.Init( pos, pos, GetPlayerMins(), GetPlayerMaxs() );

	CTraceFilterWars traceFilter( mv->m_nPlayerHandle.Get(), collisionGroup );

	enginetrace->TraceRay( ray, PlayerSolidMask(), &traceFilter, &pm );

	if ( (pm.contents & PlayerSolidMask()) && pm.m_pEnt )
	{
		return pm.m_pEnt->GetRefEHandle();
	}
	else
	{	
		return INVALID_EHANDLE_INDEX;
	}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool CGrabController::UpdateObject( CBasePlayer *pPlayer, float flError )
{
 	CBaseEntity *pEntity = GetAttached();
	if ( !pEntity || ComputeError() > flError || pPlayer->GetGroundEntity() == pEntity || !pEntity->VPhysicsGetObject() )
	{
		return false;
	}

	//Adrian: Oops, our object became motion disabled, let go!
	IPhysicsObject *pPhys = pEntity->VPhysicsGetObject();
	if ( pPhys && pPhys->IsMoveable() == false )
	{
		return false;
	}

	Vector forward, right, up;
	QAngle playerAngles = pPlayer->EyeAngles();
	AngleVectors( playerAngles, &forward, &right, &up );
	
	float pitch = AngleDistance(playerAngles.x,0);

	if( !m_bAllowObjectOverhead )
	{
		playerAngles.x = clamp( pitch, -75, 75 );
	}
	else
	{
		playerAngles.x = clamp( pitch, -90, 75 );
	}

	
	
	// Now clamp a sphere of object radius at end to the player's bbox
	Vector radial = physcollision->CollideGetExtent( pPhys->GetCollide(), vec3_origin, pEntity->GetAbsAngles(), -forward );
	Vector player2d = pPlayer->CollisionProp()->OBBMaxs();
	float playerRadius = player2d.Length2D();
	float radius = playerRadius + fabs(DotProduct( forward, radial ));

	float distance = 24 + ( radius * 2.0f );

	// Add the prop's distance offset
	distance += m_flDistanceOffset;

	Vector start = pPlayer->Weapon_ShootPosition();
	Vector end = start + ( forward * distance );

	trace_t	tr;
	CTraceFilterSkipTwoEntities traceFilter( pPlayer, pEntity, COLLISION_GROUP_NONE );
	Ray_t ray;
	ray.Init( start, end );
	enginetrace->TraceRay( ray, MASK_SOLID_BRUSHONLY, &traceFilter, &tr );

	if ( tr.fraction < 0.5 )
	{
		end = start + forward * (radius*0.5f);
	}
	else if ( tr.fraction <= 1.0f )
	{
		end = start + forward * ( distance - radius );
	}
	Vector playerMins, playerMaxs, nearest;
	pPlayer->CollisionProp()->WorldSpaceAABB( &playerMins, &playerMaxs );
	Vector playerLine = pPlayer->CollisionProp()->WorldSpaceCenter();
	CalcClosestPointOnLine( end, playerLine+Vector(0,0,playerMins.z), playerLine+Vector(0,0,playerMaxs.z), nearest, NULL );

	if( !m_bAllowObjectOverhead )
	{
		Vector delta = end - nearest;
		float len = VectorNormalize(delta);
		if ( len < radius )
		{
			end = nearest + radius * delta;
		}
	}

	//Show overlays of radius
	if ( g_debug_physcannon.GetBool() )
	{
		NDebugOverlay::Box( end, -Vector( 2,2,2 ), Vector(2,2,2), 0, 255, 0, true, 0 );

		NDebugOverlay::Box( GetAttached()->WorldSpaceCenter(), 
							-Vector( radius, radius, radius), 
							Vector( radius, radius, radius ),
							255, 0, 0,
							true,
							0.0f );
	}

	QAngle angles = TransformAnglesFromPlayerSpace( m_attachedAnglesPlayerSpace, pPlayer );
	
	// If it has a preferred orientation, update to ensure we're still oriented correctly.
	Pickup_GetPreferredCarryAngles( pEntity, pPlayer, pPlayer->EntityToWorldTransform(), angles );

	// We may be holding a prop that has preferred carry angles
	if ( m_bHasPreferredCarryAngles )
	{
		matrix3x4_t tmp;
		ComputePlayerMatrix( pPlayer, tmp );
		angles = TransformAnglesToWorldSpace( m_vecPreferredCarryAngles, tmp );
	}

	matrix3x4_t attachedToWorld;
	Vector offset;
	AngleMatrix( angles, attachedToWorld );
	VectorRotate( m_attachedPositionObjectSpace, attachedToWorld, offset );

	SetTargetPosition( end - offset, angles );

	return true;
}
// ----
// This is basically a regular TraceLine that uses the FilterEntity filter.
void UTIL_TraceLineFilterEntity( CBaseEntity *pEntity, const Vector &vecAbsStart, const Vector &vecAbsEnd, 
					   unsigned int mask, int nCollisionGroup, trace_t *ptr )
{
	CTraceFilterEntity traceFilter( pEntity, nCollisionGroup );
	UTIL_TraceLine( vecAbsStart, vecAbsEnd, mask, &traceFilter, ptr );
}
示例#9
0
//-----------------------------------------------------------------------------
// Purpose: Check the weapon LOS for an owner at an arbitrary position
//			If bSetConditions is true, LOS related conditions will also be set
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::WeaponLOSCondition( const Vector &ownerPos, const Vector &targetPos, bool bSetConditions )
{
	// --------------------
	// Check for occlusion
	// --------------------
	CAI_BaseNPC* npcOwner = m_hOwner.Get()->MyNPCPointer();

	// Find its relative shoot position
	Vector vecRelativeShootPosition;
	VectorSubtract( npcOwner->Weapon_ShootPosition(), npcOwner->GetAbsOrigin(), vecRelativeShootPosition );
	Vector barrelPos = ownerPos + vecRelativeShootPosition;

	// Use the custom LOS trace filter
	CWeaponLOSFilter traceFilter( m_hOwner.Get(), npcOwner->GetEnemy(), COLLISION_GROUP_BREAKABLE_GLASS );
	trace_t tr;
	UTIL_TraceLine( barrelPos, targetPos, MASK_SHOT, &traceFilter, &tr );

	// See if we completed the trace without interruption
	if ( tr.fraction == 1.0 )
	{
		if ( ai_debug_shoot_positions.GetBool() )
		{
			NDebugOverlay::Line( barrelPos, targetPos, 0, 255, 0, false, 1.0 );
		}

		return true;
	}

	CBaseEntity	*pHitEnt = tr.m_pEnt;

	CBasePlayer *pEnemyPlayer = ToBasePlayer( npcOwner->GetEnemy() );

	// is player in a vehicle? if so, verify vehicle is target and return if so (so npc shoots at vehicle)
	if ( pEnemyPlayer && pEnemyPlayer->IsInAVehicle() )
	{
		// Ok, player in vehicle, check if vehicle is target we're looking at, fire if it is
		// Also, check to see if the owner of the entity is the vehicle, in which case it's valid too.
		// This catches vehicles that use bone followers.
		CBaseEntity	*pVehicle  = pEnemyPlayer->GetVehicle()->GetVehicleEnt();
		if ( pHitEnt == pVehicle || pHitEnt->GetOwnerEntity() == pVehicle )
			return true;
	}

	// Hitting our enemy is a success case
	if ( pHitEnt == npcOwner->GetEnemy() )
	{
		if ( ai_debug_shoot_positions.GetBool() )
		{
			NDebugOverlay::Line( barrelPos, targetPos, 0, 255, 0, false, 1.0 );
		}

		return true;
	}

	// If a vehicle is blocking the view, grab its driver and use that as the combat character
	CBaseCombatCharacter *pBCC;
	IServerVehicle *pVehicle = pHitEnt->GetServerVehicle();
	if ( pVehicle )
	{
		pBCC = pVehicle->GetPassenger( );
	}
	else
	{
		pBCC = ToBaseCombatCharacter( pHitEnt );
	}

	if ( pBCC ) 
	{
		if ( npcOwner->IRelationType( pBCC ) == D_HT )
			return true;

		if ( bSetConditions )
		{
			npcOwner->SetCondition( COND_WEAPON_BLOCKED_BY_FRIEND );
		}
	}
	else if ( bSetConditions )
	{
		npcOwner->SetCondition( COND_WEAPON_SIGHT_OCCLUDED );
		npcOwner->SetEnemyOccluder( pHitEnt );

		if( ai_debug_shoot_positions.GetBool() )
		{
			NDebugOverlay::Line( tr.startpos, tr.endpos, 255, 0, 0, false, 1.0 );
		}
	}

	return false;
}
示例#10
0
void C_CFPlayer::CalcChaseCamView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov)
{
	C_CFPlayer *pTarget = ToCFPlayer(GetObserverTarget());

	if ( !pTarget ) 
	{
		// just copy a save in-map position
		VectorCopy( EyePosition(), eyeOrigin );
		VectorCopy( EyeAngles(), eyeAngles );
		return;
	};

	// If our target isn't visible, we're at a camera point of some kind.
	// Instead of letting the player rotate around an invisible point, treat
	// the point as a fixed camera.
	if ( !pTarget->GetBaseAnimating() && !pTarget->GetModel() )
	{
		CalcRoamingView( eyeOrigin, eyeAngles, fov );
		return;
	}

	// The following code was ripped from CCFInput::CAM_ThirdPersonNormalThink.
	// Should probably delete it and move that code to C_CFPlayer so that it can be used here too.

	eyeAngles = pTarget->EyeAngles();

	Vector vecEngineForward, vecEngineRight, vecEngineUp;
	AngleVectors(eyeAngles, &vecEngineForward, &vecEngineRight, &vecEngineUp);

	Vector vecEngineForward2D;
	AngleVectors(QAngle(0, eyeAngles[YAW], 0), &vecEngineForward2D);

	// Don't use EyePosition() because that changes depending on the animation.
	Vector vecCameraCenter = pTarget->GetAbsOrigin() + VEC_VIEW;

	m_bThirdPositionMelee = true;
	if (pTarget->GetPrimaryWeapon() && !pTarget->GetPrimaryWeapon()->IsMeleeWeapon())
		m_bThirdPositionMelee = false;
	if (pTarget->GetSecondaryWeapon() && !pTarget->GetSecondaryWeapon()->IsMeleeWeapon())
		m_bThirdPositionMelee = false;

	Vector vecRearRightPosition = vecCameraCenter + vecEngineRight * cvar->FindVar("cam_right")->GetFloat() - vecEngineForward * cvar->FindVar("cam_back")->GetFloat();
	Vector vecRearMeleePosition = vecCameraCenter + vecEngineRight * cvar->FindVar("cam_right_melee")->GetFloat() - vecEngineForward * cvar->FindVar("cam_back_melee")->GetFloat();

	m_flThirdPositionMeleeWeight = Approach(m_bThirdPositionMelee?0:1, m_flThirdPositionMeleeWeight, gpGlobals->frametime * (1/cvar->FindVar("cam_switchtime")->GetFloat()));

	float flWeight = Gain(m_flThirdPositionMeleeWeight, 0.8f);

	eyeOrigin = vecRearMeleePosition * (1-flWeight) + vecRearRightPosition * flWeight;

	if ( pTarget )
	{
		trace_t trace;

		// Trace back to see if the camera is in a wall.
		CTraceFilterNoNPCsOrPlayer traceFilter( pTarget, COLLISION_GROUP_NONE );
		UTIL_TraceHull( vecCameraCenter, eyeOrigin,
			Vector(-9,-9,-9), Vector(9,9,9),
			MASK_SOLID, &traceFilter, &trace );

		if( trace.fraction < 1.0 )
			eyeOrigin = trace.endpos;
	}

	fov = GetFOV();
}
示例#11
0
//-----------------------------------------------------------------------------
// Purpose: For create nodes in wc edit mode
// Input  :
// Output :
//-----------------------------------------------------------------------------
void NWCEdit::CreateAINode( CBasePlayer *pPlayer )
{
	// -------------------------------------------------------------
	//  Check that WC is running with the right map version
	// -------------------------------------------------------------
	if ( !IsWCVersionValid() || !pPlayer )
		return;

	pPlayer->AddSolidFlags( FSOLID_NOT_SOLID );

	int hullType = g_pAINetworkManager->GetEditOps()->m_iHullDrawNum;

	// -----------------------------------
	//  Get position of node to create
	// -----------------------------------
	Vector vNewNodePos = vec3_origin;
	bool bPositionValid = false;
	if (g_pAINetworkManager->GetEditOps()->m_bAirEditMode)
	{
		vNewNodePos = NWCEdit::AirNodePlacementPosition();

		// Make sure we can see the node
		trace_t tr;
		UTIL_TraceLine(pPlayer->EyePosition(), vNewNodePos, MASK_NPCSOLID_BRUSHONLY, pPlayer, COLLISION_GROUP_NONE, &tr);
		if (tr.fraction == 1.0)
		{
			bPositionValid = true;
		}
	}
	else
	{
		// Place node by where the player is looking
		Vector forward;
		pPlayer->EyeVectors( &forward );
		Vector	startTrace	= pPlayer->EyePosition();
		Vector	endTrace	= pPlayer->EyePosition() + forward * MAX_TRACE_LENGTH;
		trace_t	tr;
		UTIL_TraceLine(startTrace,endTrace,MASK_NPCSOLID, pPlayer, COLLISION_GROUP_NONE, &tr );
		if ( tr.fraction != 1.0)
		{
			// Raise the end position up off the floor, place the node and drop him down
			tr.endpos.z += 48;
			vNewNodePos = tr.endpos;
			bPositionValid = true;
		}
	}

	// -------------------------------------------------------------------------------
	// Now check that this is a valid location for the new node bu using test hull
	// -------------------------------------------------------------------------------
	if (bPositionValid)
	{
		CBaseEntity *testHull = (CBaseEntity*)CAI_TestHull::GetTestHull();

		// Set the size of the test hull
		UTIL_SetSize(testHull, NAI_Hull::Mins(hullType), NAI_Hull::Maxs(hullType));

		// Set origin of test hull
		testHull->SetLocalOrigin( vNewNodePos );

		// -----------------------------------------------------------------------
		// If a ground node, drop to floor and make sure can stand at test postion
		// -----------------------------------------------------------------------
		if (!g_pAINetworkManager->GetEditOps()->m_bAirEditMode)
		{
			UTIL_DropToFloor( testHull, MASK_NPCSOLID );
			vNewNodePos = testHull->GetAbsOrigin();
			CTraceFilterSimple traceFilter( testHull, COLLISION_GROUP_NONE );
			if (!UTIL_CheckBottom(testHull, &traceFilter, sv_stepsize.GetFloat()))
			{
				CAI_TestHull::ReturnTestHull();
				bPositionValid = false;
				goto DoneCreate;
			}
		}

		// -----------------------------------------------------------------------
		// Make sure hull fits at location by seeing if it can move up a fraction
		// -----------------------------------------------------------------------
		Vector vUpBit = testHull->GetAbsOrigin();
		vUpBit.z += 1;
		trace_t tr;
		UTIL_TraceHull( testHull->GetAbsOrigin(), vUpBit, NAI_Hull::Mins(hullType), 
			NAI_Hull::Maxs(hullType), MASK_NPCSOLID, testHull, COLLISION_GROUP_NONE, &tr );
		if (tr.startsolid || tr.fraction != 1.0)
		{
			CAI_TestHull::ReturnTestHull();
			bPositionValid = false;
			goto DoneCreate;
		}

		// <<TEMP>> Round position till DS fixed WC bug
		testHull->SetLocalOrigin( Vector( floor(testHull->GetAbsOrigin().x),
			floor(testHull->GetAbsOrigin().y ), floor(testHull->GetAbsOrigin().z) ) );

		// ---------------------------------------
		//  Send new node to WC
		// ---------------------------------------
		int status;
		if (g_pAINetworkManager->GetEditOps()->m_bAirEditMode)
		{
			status = Editor_CreateNode("info_node_air", g_pAINetworkManager->GetEditOps()->m_nNextWCIndex, testHull->GetLocalOrigin().x, testHull->GetLocalOrigin().y, testHull->GetLocalOrigin().z, false);
		}
		else
		{
			// Create slightly higher in WC so it can be dropped when its loaded again
			Vector origin = testHull->GetLocalOrigin();
			origin.z += 24.0;
			testHull->SetLocalOrigin( origin );
			status = Editor_CreateNode("info_node", g_pAINetworkManager->GetEditOps()->m_nNextWCIndex, testHull->GetLocalOrigin().x, testHull->GetLocalOrigin().y, testHull->GetLocalOrigin().z, false);
		}
		if (status == Editor_BadCommand)
		{
			Msg( "Worldcraft failed on creation...\n" );
			CAI_TestHull::ReturnTestHull();
		}
		else if (status == Editor_OK)
		{
			// -----------------------
			// Create a new ai node
			// -----------------------
			CNodeEnt *pNodeEnt;
			if (g_pAINetworkManager->GetEditOps()->m_bAirEditMode)
			{
				pNodeEnt = (CNodeEnt*)CreateEntityByName("info_node_air");
			}
			else
			{
				pNodeEnt = (CNodeEnt*)CreateEntityByName("info_node");
			}

			// Note this is a new entity being created as part of wc editing
			pNodeEnt->SetLocalOrigin( testHull->GetLocalOrigin() );
			CAI_TestHull::ReturnTestHull();

			pNodeEnt->m_NodeData.nWCNodeID =	g_pAINetworkManager->GetEditOps()->m_nNextWCIndex;

			pNodeEnt->m_debugOverlays |= OVERLAY_WC_CHANGE_ENTITY;
			pNodeEnt->Spawn();
		}	
	}

DoneCreate:
	// ----------------------------------------------------------
	// Flash a red box as a warning that the hull won't fit here
	// ----------------------------------------------------------
	if (!bPositionValid)
	{
		NDebugOverlay::Box(vNewNodePos, NAI_Hull::Mins(hullType), NAI_Hull::Maxs(hullType), 255,0,0,0,0.1);
	}

	// Restore player collidability
	pPlayer->SetSolid( SOLID_BBOX );
}
void CNPC_Portal_GroundTurret::Shoot()
{
	FireBulletsInfo_t info;

	Vector vecSrc = EyePosition();
	Vector vecDir;

	GetVectors( &vecDir, NULL, NULL );

	for( int i = 0 ; i < 1 ; i++ )
	{
		info.m_vecSrc = vecSrc;

		if( i > 0 || !GetEnemy()->IsPlayer() )
		{
			// Subsequent shots or shots at non-players random
			GetVectors( &info.m_vecDirShooting, NULL, NULL );
			info.m_vecSpread = m_vecSpread;
		}
		else
		{
			// First shot is at the enemy.
			info.m_vecDirShooting = GetActualShootTrajectory( vecSrc );
			info.m_vecSpread = VECTOR_CONE_PRECALCULATED;
		}

		info.m_iTracerFreq = 1;
		info.m_iShots = 1;
		info.m_pAttacker = this;
		info.m_flDistance = MAX_COORD_RANGE;
		info.m_iAmmoType = m_iAmmoType;

		FireBullets( info );

		trace_t tr;
		CTraceFilterSkipTwoEntities traceFilter( this, info.m_pAdditionalIgnoreEnt, COLLISION_GROUP_NONE );
		Vector vecEnd = info.m_vecSrc + vecDir * info.m_flDistance;
		AI_TraceLine( info.m_vecSrc, vecEnd, MASK_SHOT, &traceFilter, &tr );

		if ( tr.m_pEnt && !tr.m_pEnt->IsPlayer() && ( vecDir * info.m_flDistance * tr.fraction ).Length() < 16.0f )
		{
			CTakeDamageInfo damageInfo;
			damageInfo.SetAttacker( this );
			damageInfo.SetDamageType( DMG_BULLET );
			damageInfo.SetDamage( 20.0f );

			TakeDamage( damageInfo );

			EmitSound( "NPC_FloorTurret.DryFire" );
		}
	}

	// Do the AR2 muzzle flash
	CEffectData data;
	data.m_nEntIndex = entindex();
	data.m_nAttachmentIndex = LookupAttachment( "eyes" );
	data.m_flScale = 1.0f;
	data.m_fFlags = MUZZLEFLASH_COMBINE;
	DispatchEffect( "MuzzleFlash", data );

	EmitSound( "NPC_FloorTurret.ShotSounds" );

	m_flTimeNextShoot = gpGlobals->curtime + 0.09;
}
示例#13
0
			if ( pEntity->IsEffectActive( EF_NODRAW ) )
				return false;

			for ( int i = 0; i < ARRAYSIZE(ppszIgnoredClasses); i++ )
			{
				if ( pEntity->ClassMatches( ppszIgnoredClasses[i] ) )
					return false;
			}


			return CTraceFilterSimple::ShouldHitEntity( pServerEntity, contentsMask );
		}
	};

	trace_t trace;
	CTraceFilterValidForDecal traceFilter( this, COLLISION_GROUP_NONE );
	int entityIndex, modelIndex = 0;

	Vector position = GetAbsOrigin();
	UTIL_TraceLine( position - Vector(5,5,5), position + Vector(5,5,5),  MASK_SOLID, &traceFilter, &trace );

	bool canDraw = true;

	entityIndex = trace.m_pEnt ? (short)trace.m_pEnt->entindex() : 0;
	if ( entityIndex )
	{
		CBaseEntity *ent = trace.m_pEnt;
		if ( ent )
		{
			modelIndex = ent->GetModelIndex();
			VectorITransform( GetAbsOrigin(), ent->EntityToWorldTransform(), position );
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTFFlameThrower::PrimaryAttack()
{
	// Are we capable of firing again?
	if ( m_flNextPrimaryAttack > gpGlobals->curtime )
		return;

	// Get the player owning the weapon.
	CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
	if ( !pOwner )
		return;

	if ( !CanAttack() )
	{
#if defined ( CLIENT_DLL )
		StopFlame();
#endif
		m_iWeaponState = FT_STATE_IDLE;
		return;
	}

	CalcIsAttackCritical();

	// Because the muzzle is so long, it can stick through a wall if the player is right up against it.
	// Make sure the weapon can't fire in this condition by tracing a line between the eye point and the end of the muzzle.
	trace_t trace;	
	Vector vecEye = pOwner->EyePosition();
	Vector vecMuzzlePos = GetVisualMuzzlePos();
	CTraceFilterIgnoreObjects traceFilter( this, COLLISION_GROUP_NONE );
	UTIL_TraceLine( vecEye, vecMuzzlePos, MASK_SOLID, &traceFilter, &trace );
	if ( trace.fraction < 1.0 && ( !trace.m_pEnt || trace.m_pEnt->m_takedamage == DAMAGE_NO ) )
	{
		// there is something between the eye and the end of the muzzle, most likely a wall, don't fire, and stop firing if we already are
		if ( m_iWeaponState > FT_STATE_IDLE )
		{
#if defined ( CLIENT_DLL )
			StopFlame();
#endif
			m_iWeaponState = FT_STATE_IDLE;
		}
		return;
	}

	switch ( m_iWeaponState )
	{
	case FT_STATE_IDLE:
	case FT_STATE_AIRBLASTING:
		{
			// Just started, play PRE and start looping view model anim

			pOwner->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRE );

			SendWeaponAnim( ACT_VM_PRIMARYATTACK );

			m_flStartFiringTime = gpGlobals->curtime + 0.16;	// 5 frames at 30 fps

			m_iWeaponState = FT_STATE_STARTFIRING;
		}
		break;
	case FT_STATE_STARTFIRING:
		{
			// if some time has elapsed, start playing the looping third person anim
			if ( gpGlobals->curtime > m_flStartFiringTime )
			{
				m_iWeaponState = FT_STATE_FIRING;
				m_flNextPrimaryAttackAnim = gpGlobals->curtime;
			}
		}
		break;
	case FT_STATE_FIRING:
		{
			if ( gpGlobals->curtime >= m_flNextPrimaryAttackAnim )
			{
				pOwner->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );
				m_flNextPrimaryAttackAnim = gpGlobals->curtime + 1.4;		// fewer than 45 frames!
			}
		}
		break;

	default:
		break;
	}

#ifdef CLIENT_DLL
	// Restart our particle effect if we've transitioned across water boundaries
	if ( m_iParticleWaterLevel != -1 && pOwner->GetWaterLevel() != m_iParticleWaterLevel )
	{
		if ( m_iParticleWaterLevel == WL_Eyes || pOwner->GetWaterLevel() == WL_Eyes )
		{
			RestartParticleEffect();
		}
	}
#endif

#ifdef CLIENT_DLL
	// Handle the flamethrower light
	if (tf2c_muzzlelight.GetBool())
	{
		dlight_t *dl = effects->CL_AllocDlight(LIGHT_INDEX_MUZZLEFLASH + index);
		dl->origin = vecMuzzlePos;
		dl->color.r = 255;
		dl->color.g = 100;
		dl->color.b = 10;
		dl->die = gpGlobals->curtime + 0.01f;
		dl->radius = 240.f;
		dl->decay = 512.0f;
		dl->style = 5;
	}
#endif

#if !defined (CLIENT_DLL)
	// Let the player remember the usercmd he fired a weapon on. Assists in making decisions about lag compensation.
	pOwner->NoteWeaponFired();

	pOwner->SpeakWeaponFire();
	CTF_GameStats.Event_PlayerFiredWeapon( pOwner, m_bCritFire );

	// Move other players back to history positions based on local player's lag
	lagcompensation->StartLagCompensation( pOwner, pOwner->GetCurrentCommand() );
#endif

	float flFiringInterval = m_pWeaponInfo->GetWeaponData( m_iWeaponMode ).m_flTimeFireDelay;
	CALL_ATTRIB_HOOK_FLOAT( flFiringInterval, mult_postfiredelay );

	// Don't attack if we're underwater
	if ( pOwner->GetWaterLevel() != WL_Eyes )
	{
		// Find eligible entities in a cone in front of us.
		Vector vOrigin = pOwner->Weapon_ShootPosition();
		Vector vForward, vRight, vUp;
		QAngle vAngles = pOwner->EyeAngles() + pOwner->GetPunchAngle();
		AngleVectors( vAngles, &vForward, &vRight, &vUp );

		#define NUM_TEST_VECTORS	30

#ifdef CLIENT_DLL
		bool bWasCritical = m_bCritFire;
#endif

		// Burn & Ignite 'em
		int iDmgType = g_aWeaponDamageTypes[ GetWeaponID() ];
		m_bCritFire = IsCurrentAttackACrit();
		if ( m_bCritFire )
		{
			iDmgType |= DMG_CRITICAL;
		}

#ifdef CLIENT_DLL
		if ( bWasCritical != m_bCritFire )
		{
			RestartParticleEffect();
		}
#endif


#ifdef GAME_DLL
		// create the flame entity
		int iDamagePerSec = m_pWeaponInfo->GetWeaponData( m_iWeaponMode ).m_nDamage;
		float flDamage = (float)iDamagePerSec * flFiringInterval;
		CALL_ATTRIB_HOOK_FLOAT( flDamage, mult_dmg );
		CTFFlameEntity::Create( GetFlameOriginPos(), pOwner->EyeAngles(), this, iDmgType, flDamage );
#endif
	}

#ifdef GAME_DLL
	// Figure how much ammo we're using per shot and add it to our remainder to subtract.  (We may be using less than 1.0 ammo units
	// per frame, depending on how constants are tuned, so keep an accumulator so we can expend fractional amounts of ammo per shot.)
	// Note we do this only on server and network it to client.  If we predict it on client, it can get slightly out of sync w/server
	// and cause ammo pickup indicators to appear
	
	float flAmmoPerSecond = TF_FLAMETHROWER_AMMO_PER_SECOND_PRIMARY_ATTACK;
	CALL_ATTRIB_HOOK_FLOAT( flAmmoPerSecond, mult_flame_ammopersec );

	m_flAmmoUseRemainder += flAmmoPerSecond * flFiringInterval;
	// take the integer portion of the ammo use accumulator and subtract it from player's ammo count; any fractional amount of ammo use
	// remains and will get used in the next shot
	int iAmmoToSubtract = (int) m_flAmmoUseRemainder;
	if ( iAmmoToSubtract > 0 )
	{
		pOwner->RemoveAmmo( iAmmoToSubtract, m_iPrimaryAmmoType );
		m_flAmmoUseRemainder -= iAmmoToSubtract;
		// round to 2 digits of precision
		m_flAmmoUseRemainder = (float) ( (int) (m_flAmmoUseRemainder * 100) ) / 100.0f;
	}
#endif

	m_flNextPrimaryAttack = gpGlobals->curtime + flFiringInterval;
	m_flTimeWeaponIdle = gpGlobals->curtime + flFiringInterval;

#if !defined (CLIENT_DLL)
	lagcompensation->FinishLagCompensation( pOwner );
#endif
}
示例#15
0
bool CFlashlightEffect::ComputeLightPosAndOrientation( const Vector &vecPos, const Vector &vecForward, const Vector &vecRight, const Vector &vecUp,
														Vector& vecFinalPos, Quaternion& quatOrientation, bool bTracePlayers )
{
	const float flEpsilon = 0.1f;			// Offset flashlight position along vecUp
	float flDistCutoff = r_flashlighttracedistcutoff.GetFloat();
	const float flDistDrag = 0.2;
	bool bDebugVis = r_flashlightvisualizetrace.GetBool();

	C_BasePlayer *pPlayer = UTIL_PlayerByIndex( m_nEntIndex );
	if ( !pPlayer )
	{

		pPlayer = C_BasePlayer::GetLocalPlayer();

		if ( !pPlayer )
		{
			Assert( false );
			return false;
		}
	}

	// We will lock some of the flashlight params if player is on a ladder, to prevent oscillations due to the trace-rays
	bool bPlayerOnLadder = ( pPlayer->GetMoveType() == MOVETYPE_LADDER );

	CTraceFilterSkipPlayerAndViewModel traceFilter( pPlayer, bTracePlayers );

	//	Vector vOrigin = vecPos + r_flashlightoffsety.GetFloat() * vecUp;
	Vector vecOffset;
	pPlayer->GetFlashlightOffset( vecForward, vecRight, vecUp, &vecOffset );
	Vector vOrigin = vecPos + vecOffset;

	// Not on ladder...trace a hull
	if ( !bPlayerOnLadder ) 
	{
		Vector vecPlayerEyePos = pPlayer->GetRenderOrigin() + pPlayer->GetViewOffset();

		trace_t pmOriginTrace;
		UTIL_TraceHull( vecPlayerEyePos, vOrigin, Vector(-2, -2, -2), Vector(2, 2, 2), ( MASK_SOLID & ~(CONTENTS_HITBOX) ) | CONTENTS_WINDOW | CONTENTS_GRATE, &traceFilter, &pmOriginTrace );//1

		if ( bDebugVis )
		{
			debugoverlay->AddBoxOverlay( pmOriginTrace.endpos, Vector( -2, -2, -2 ), Vector( 2, 2, 2 ), QAngle( 0, 0, 0 ), 0, 255, 0, 16, 0 );
			if ( pmOriginTrace.DidHit() || pmOriginTrace.startsolid )
			{
				debugoverlay->AddLineOverlay( pmOriginTrace.startpos, pmOriginTrace.endpos, 255, 128, 128, true, 0 );
			}
			else
			{
				debugoverlay->AddLineOverlay( pmOriginTrace.startpos, pmOriginTrace.endpos, 255, 0, 0, true, 0 );
			}
		}

		if ( pmOriginTrace.DidHit() || pmOriginTrace.startsolid )
		{
			vOrigin = pmOriginTrace.endpos;
		}
		else
		{
			if ( pPlayer->m_vecFlashlightOrigin != vecPlayerEyePos )
			{
				vOrigin = vecPos;
			}
		}
	}
	else // on ladder...skip the above hull trace
	{
		vOrigin = vecPos;
	}

	// Now do a trace along the flashlight direction to ensure there is nothing within range to pull back from
	int iMask = MASK_OPAQUE_AND_NPCS;
	iMask &= ~CONTENTS_HITBOX;
	iMask |= CONTENTS_WINDOW | CONTENTS_GRATE | CONTENTS_IGNORE_NODRAW_OPAQUE;

	Vector vTarget = vOrigin + vecForward * r_flashlightfar.GetFloat();

	// Work with these local copies of the basis for the rest of the function
	Vector vDir   = vTarget - vOrigin;
	Vector vRight = vecRight;
	Vector vUp    = vecUp;
	VectorNormalize( vDir   );
	VectorNormalize( vRight );
	VectorNormalize( vUp    );

	// Orthonormalize the basis, since the flashlight texture projection will require this later...
	vUp -= DotProduct( vDir, vUp ) * vDir;
	VectorNormalize( vUp );
	vRight -= DotProduct( vDir, vRight ) * vDir;
	VectorNormalize( vRight );
	vRight -= DotProduct( vUp, vRight ) * vUp;
	VectorNormalize( vRight );

	AssertFloatEquals( DotProduct( vDir, vRight ), 0.0f, 1e-3 );
	AssertFloatEquals( DotProduct( vDir, vUp    ), 0.0f, 1e-3 );
	AssertFloatEquals( DotProduct( vRight, vUp  ), 0.0f, 1e-3 );

	trace_t pmDirectionTrace;
	UTIL_TraceHull( vOrigin, vTarget, Vector( -1.5, -1.5, -1.5 ), Vector( 1.5, 1.5, 1.5 ), iMask, &traceFilter, &pmDirectionTrace );//.5

	if ( bDebugVis )
	{
		debugoverlay->AddBoxOverlay( pmDirectionTrace.endpos, Vector( -4, -4, -4 ), Vector( 4, 4, 4 ), QAngle( 0, 0, 0 ), 0, 0, 255, 16, 0 );
		debugoverlay->AddLineOverlay( vOrigin, pmDirectionTrace.endpos, 255, 0, 0, false, 0 );
	}

	float flTargetPullBackDist = 0.0f;
	float flDist = (pmDirectionTrace.endpos - vOrigin).Length();

	if ( flDist < flDistCutoff )
	{
		// We have an intersection with our cutoff range
		// Determine how far to pull back, then trace to see if we are clear
		float flPullBackDist = bPlayerOnLadder ? r_flashlightladderdist.GetFloat() : flDistCutoff - flDist;	// Fixed pull-back distance if on ladder

		flTargetPullBackDist = flPullBackDist;

		if ( !bPlayerOnLadder )
		{
			trace_t pmBackTrace;
			// start the trace away from the actual trace origin a bit, to avoid getting stuck on small, close "lips"
			UTIL_TraceHull( vOrigin - vDir * ( flDistCutoff * r_flashlightbacktraceoffset.GetFloat() ), vOrigin - vDir * ( flPullBackDist - flEpsilon ),
				Vector( -1.5f, -1.5f, -1.5f ), Vector( 1.5f, 1.5f, 1.5f ), iMask, &traceFilter, &pmBackTrace );

			if ( bDebugVis )
			{
				debugoverlay->AddLineOverlay( pmBackTrace.startpos, pmBackTrace.endpos, 255, 0, 255, true, 0 );
			}

			if( pmBackTrace.DidHit() )
			{
				// We have an intersection behind us as well, so limit our flTargetPullBackDist
				float flMaxDist = (pmBackTrace.endpos - vOrigin).Length() - flEpsilon;
				flTargetPullBackDist = MIN( flMaxDist, flTargetPullBackDist );
				//m_flCurrentPullBackDist = MIN( flMaxDist, m_flCurrentPullBackDist );	// possible pop
			}
		}
	}

	if ( bDebugVis )
	{
		// visualize pullback
		debugoverlay->AddBoxOverlay( vOrigin - vDir * m_flCurrentPullBackDist, Vector( -2, -2, -2 ), Vector( 2, 2, 2 ), QAngle( 0, 0, 0 ), 255, 255, 0, 16, 0 );
		debugoverlay->AddBoxOverlay( vOrigin - vDir * flTargetPullBackDist, Vector( -1, -1, -1 ), Vector( 1, 1, 1 ), QAngle( 0, 0, 0 ), 128, 128, 0, 16, 0 );
	}

	m_flCurrentPullBackDist = Lerp( flDistDrag, m_flCurrentPullBackDist, flTargetPullBackDist );
	m_flCurrentPullBackDist = MIN( m_flCurrentPullBackDist, flDistCutoff );	// clamp to max pullback dist
	vOrigin = vOrigin - vDir * m_flCurrentPullBackDist;

	vecFinalPos = vOrigin;
	BasisToQuaternion( vDir, vRight, vUp, quatOrientation );

	return true;
}
示例#16
0
void CSDKInput::CAM_Think( void )
{
	VPROF("CAM_Think");

	Vector idealAngles;
	Vector camOffset;
	QAngle viewangles;
	
	if( !CAM_IsThirdPerson() )
		return;

	ConVarRef cam_idealpitch( "cam_idealpitch" );
	ConVarRef cam_idealyaw( "cam_idealyaw" );
	ConVarRef cam_idealdist( "cam_idealdist" );

	idealAngles[ PITCH ] = cam_idealpitch.GetFloat();
	idealAngles[ YAW ]   = cam_idealyaw.GetFloat();
	idealAngles[ DIST ]  = cam_idealdist.GetFloat();

	// Obtain engine view angles and if they popped while the camera was static,
	// fix the camera angles as well
	engine->GetViewAngles( viewangles );

	// bring the pitch values back into a range that MoveToward can handle
	if ( idealAngles[ PITCH ] > 180 )
		idealAngles[ PITCH ] -= 360;
	else if ( idealAngles[ PITCH ] < -180 )
		idealAngles[ PITCH ] += 360;

	// bring the yaw values back into a range that MoveToward can handle
	// --
	// Vitaliy: going with >= 180 and <= -180.
	// This introduces a potential discontinuity when looking directly at model face
	// as camera yaw will be jumping from +180 to -180 and back, but when working with
	// the camera allows smooth rotational transitions from left to right and back.
	// Otherwise one of the transitions that has ">"-comparison will be locked.
	// --
	if ( idealAngles[ YAW ] >= 180 )
		idealAngles[ YAW ] -= 360;
	else if ( idealAngles[ YAW ] <= -180 )
		idealAngles[ YAW ] += 360;

	ConVarRef c_minpitch( "c_minpitch" );
	ConVarRef c_maxpitch( "c_maxpitch" );
	ConVarRef c_minyaw( "c_minyaw" );
	ConVarRef c_maxyaw( "c_maxyaw" );
	ConVarRef c_mindistance( "c_mindistance" );
	ConVarRef c_maxdistance( "c_maxdistance" );

	// clamp pitch, yaw and dist...
	idealAngles[ PITCH ] = clamp( idealAngles[ PITCH ], c_minpitch.GetFloat(), c_maxpitch.GetFloat() );
	idealAngles[ YAW ]   = clamp( idealAngles[ YAW ], c_minyaw.GetFloat(), c_maxyaw.GetFloat() );
	idealAngles[ DIST ]  = clamp( idealAngles[ DIST ], c_mindistance.GetFloat(), c_maxdistance.GetFloat() );

	// update ideal angles
	cam_idealpitch.SetValue( idealAngles[ PITCH ] );
	cam_idealyaw.SetValue( idealAngles[ YAW ] );
	cam_idealdist.SetValue( idealAngles[ DIST ] );
	
	// Move the CameraOffset "towards" the idealAngles
	// Note: CameraOffset = viewangle + idealAngle
	CAM_GetCameraOffset( camOffset );

	ConVarRef cam_snapto( "cam_snapto" );
	if( cam_snapto.GetInt() )
	{
		camOffset[ YAW ] = cam_idealyaw.GetFloat() + viewangles[ YAW ];
		camOffset[ PITCH ] = cam_idealpitch.GetFloat() + viewangles[ PITCH ];
		camOffset[ DIST ] = cam_idealdist.GetFloat();
	}
	else
	{
		ConVarRef cam_ideallag( "cam_ideallag" );
		float lag = max( 1, 1 + cam_ideallag.GetFloat() );

		if( camOffset[ YAW ] - viewangles[ YAW ] != cam_idealyaw.GetFloat() )
			camOffset[ YAW ] = MoveToward( camOffset[ YAW ], cam_idealyaw.GetFloat() + viewangles[ YAW ], lag );
		
		if( camOffset[ PITCH ] - viewangles[ PITCH ] != cam_idealpitch.GetFloat() )
			camOffset[ PITCH ] = MoveToward( camOffset[ PITCH ], cam_idealpitch.GetFloat() + viewangles[ PITCH ], lag );
		
		if( abs( camOffset[ DIST ] - cam_idealdist.GetFloat() ) < 2.0 )
			camOffset[ DIST ] = cam_idealdist.GetFloat();
		else
			camOffset[ DIST ] += ( cam_idealdist.GetFloat() - camOffset[ DIST ] ) / lag;
	}

	// move the camera closer to the player if it hit something
	trace_t trace;
	C_BasePlayer* localPlayer = C_BasePlayer::GetLocalPlayer();

	if ( localPlayer )
	{
		Vector camForward;

		// find our player's origin, and from there, the eye position
		Vector origin = localPlayer->GetLocalOrigin();
		origin += localPlayer->GetViewOffset();

		// get the forward vector
		AngleVectors( QAngle(camOffset[ PITCH ], camOffset[ YAW ], 0), &camForward, NULL, NULL );

		// use our previously #defined hull to collision trace
		CTraceFilterSimple traceFilter( localPlayer, COLLISION_GROUP_NONE );
		UTIL_TraceHull( origin, origin - (camForward * camOffset[ DIST ]),
			Vector(-CAM_HULL_OFFSET, -CAM_HULL_OFFSET, -CAM_HULL_OFFSET), Vector(CAM_HULL_OFFSET, CAM_HULL_OFFSET, CAM_HULL_OFFSET),
			MASK_SOLID, &traceFilter, &trace );

		// move the camera closer if it hit something
		if( trace.fraction < 1.0 )
		{
			camOffset[ DIST ] *= trace.fraction;
		}

		// For now, I'd rather see the insade of a player model than punch the camera through a wall
		// might try the fade out trick at some point
		//if( camOffset[ DIST ] < CAM_MIN_DIST )
		//    camOffset[ DIST ] = CAM_MIN_DIST; // clamp up to minimum
	}

	ConVarRef cam_showangles( "cam_showangles" );
	if ( cam_showangles.GetInt() )
	{
		engine->Con_NPrintf( 4, "Pitch: %6.1f   Yaw: %6.1f %38s", viewangles[ PITCH ], viewangles[ YAW ], "view angles" );
		engine->Con_NPrintf( 6, "Pitch: %6.1f   Yaw: %6.1f   Dist: %6.1f %19s", cam_idealpitch.GetFloat(), cam_idealyaw.GetFloat(), cam_idealdist.GetFloat(), "ideal angles" );
		engine->Con_NPrintf( 8, "Pitch: %6.1f   Yaw: %6.1f   Dist: %6.1f %16s", camOffset[ PITCH ], camOffset[ YAW ], camOffset[ DIST ], "camera offset" );
	}

	QAngle angOffset;
	angOffset.x = camOffset.x;
	angOffset.y = camOffset.y;
	angOffset.z = camOffset.z;

	CAM_SetCameraThirdData(NULL, angOffset);
}
示例#17
0
void CThirdPersonManager::PositionCamera( CBasePlayer *pPlayer, QAngle angles )
{
	if ( pPlayer )
	{
		trace_t trace;

		Vector camForward, camRight, camUp;

		// find our player's origin, and from there, the eye position
		Vector origin = pPlayer->GetLocalOrigin();
		origin += pPlayer->GetViewOffset();

		AngleVectors( angles, &camForward, &camRight, &camUp );

		Vector endPos = origin;

		Vector vecCamOffset = endPos + (camForward * - GetDesiredCameraOffset()[DIST_FORWARD]) + (camRight * GetDesiredCameraOffset()[ DIST_RIGHT ]) + (camUp * GetDesiredCameraOffset()[ DIST_UP ] );

		// use our previously #defined hull to collision trace
		CTraceFilterSimple traceFilter( pPlayer, COLLISION_GROUP_NONE );
		UTIL_TraceHull( endPos, vecCamOffset, CAM_HULL_MIN, CAM_HULL_MAX, MASK_SOLID & ~CONTENTS_MONSTER, &traceFilter, &trace );

		if ( trace.fraction != m_flTargetFraction )
		{
			m_flLerpTime = gpGlobals->curtime;
		}

		m_flTargetFraction = trace.fraction;
		m_flTargetUpFraction = 1.0f;

		//If we're getting closer to a wall snap the fraction right away.
		if ( m_flTargetFraction < m_flFraction )
		{
			m_flFraction = m_flTargetFraction;
			m_flLerpTime = gpGlobals->curtime;
		}


		// move the camera closer if it hit something
		if( trace.fraction < 1.0  )
		{
			m_vecCameraOffset[ DIST ] *= trace.fraction;

			UTIL_TraceHull( endPos, endPos + (camForward * - GetDesiredCameraOffset()[DIST_FORWARD]), CAM_HULL_MIN, CAM_HULL_MAX, MASK_SOLID & ~CONTENTS_MONSTER, &traceFilter, &trace );

			if ( trace.fraction != 1.0f )
			{
				if ( trace.fraction != m_flTargetUpFraction )
				{
					m_flUpLerpTime = gpGlobals->curtime;
				}

				m_flTargetUpFraction = trace.fraction;

				if ( m_flTargetUpFraction < m_flUpFraction )
				{
					m_flUpFraction = trace.fraction;
					m_flUpLerpTime = gpGlobals->curtime;
				}
			}
		}
	}
}
	void ItemPostFrame()
	{
		CBasePlayer *pPlayer = dynamic_cast<CBasePlayer*>(GetOwner());
		if( !pPlayer )
			return;

		if ( pPlayer->m_afButtonReleased & IN_ATTACK )
		{
			CancelPrimaryAttack();
		}
					
		trace_t tr;
		Vector eyePos, eyeForward;
		pPlayer->EyePositionAndVectors( &eyePos, &eyeForward, NULL, NULL );

		CTraceFilterSkipTwoEntities traceFilter( pPlayer, this, COLLISION_GROUP_NONE );
		UTIL_TraceLine( eyePos, eyePos + eyeForward * MAX_TRACE_LENGTH, MASK_SHOT, &traceFilter, &tr );

		if( !m_hBeam )
		{
			if ( gpGlobals->curtime >= m_flBeamTime )
			{
#ifndef CLIENT_DLL
				m_hBeam = CREATE_ENTITY( CBeam, "env_beam" );

				if ( m_hBeam )
				{
					m_hBeam->BeamInit( "sprites/lgtning.vmt", 6.5f );
					m_hBeam->PointEntInit( tr.endpos, pPlayer->GetViewModel(0) );
					m_hBeam->SetScrollRate( -10.f );
					m_hBeam->SetNoise( 1 );
					m_hBeam->SetEndAttachment( LookupAttachment("muzzle") );
					m_hBeam->Spawn();
				}
#endif
				SendWeaponAnim( ACT_VM_PRIMARYATTACK );
			}
			
			if ( m_flBeamTime == FLT_MAX )
				BaseClass::ItemPostFrame();
		}
		else
		{
			if ( gpGlobals->curtime >= m_flDamageTime )
			{
				GetOwner()->RemoveAmmo( 1, GetPrimaryAmmoType() );
#ifndef CLIENT_DLL					
				if( tr.fraction != 1.0 && tr.m_pEnt )
				{
					ClearMultiDamage();
					Vector dir = tr.endpos - m_hBeam->GetAbsEndPos();
					VectorNormalize( dir );
	
					const float flDamage = BEAM_DAMAGE;

					CTakeDamageInfo info( m_hBeam, GetOwner(), flDamage, DMG_SHOCK );
					CalculateMeleeDamageForce( &info, dir, tr.endpos );
					tr.m_pEnt->DispatchTraceAttack( info, dir, &tr );
					ApplyMultiDamage();

					RadiusDamage( CTakeDamageInfo( m_hBeam, GetOwner(), flDamage * 0.25f, DMG_SHOCK ), tr.endpos, 16.0f, CLASS_NONE, NULL );
				}
#endif

				if ( !HasPrimaryAmmo() )
					CancelPrimaryAttack();

				m_flDamageTime = gpGlobals->curtime + DAMAGE_TICK;
			}

			m_hBeam->SetStartPos( tr.endpos );
		}
	}
示例#19
0
//-----------------------------------------------------------------------------
// Computes the bounding box of a beam local to the origin of the beam
//-----------------------------------------------------------------------------
void CBeam::ComputeBounds( Vector& mins, Vector& maxs )
{
	Vector vecAbsStart = GetAbsStartPos();
	Vector vecAbsEnd = GetAbsEndPos();

	// May need extra points for creating the min/max bounds
	bool bUseExtraPoints = false;
	Vector vecAbsExtra1, vecAbsExtra2;

#ifdef PORTAL
	CBaseEntity *pStartEntity = GetStartEntityPtr();

	CTraceFilterSkipClassname traceFilter( pStartEntity, "prop_energy_ball", COLLISION_GROUP_NONE );

	ITraceFilter *pEntityBeamTraceFilter = NULL;
	if ( pStartEntity )
		pEntityBeamTraceFilter = pStartEntity->GetBeamTraceFilter();

	CTraceFilterChain traceFilterChain( &traceFilter, pEntityBeamTraceFilter );

	bUseExtraPoints = UTIL_Portal_Trace_Beam( this, vecAbsStart, vecAbsEnd, vecAbsExtra1, vecAbsExtra2, &traceFilterChain );
#endif

	switch( GetType() )
	{
	case BEAM_LASER:
	case BEAM_ENTS:
	case BEAM_SPLINE:
	case BEAM_ENTPOINT:
		{
			// Compute the bounds here...
			Vector attachmentPoint( 0, 0, 0 );
			mins.Init( 99999, 99999, 99999 );
			maxs.Init( -99999, -99999, -99999 );
			for (int i = 0; i < m_nNumBeamEnts; ++i )
			{
				C_BaseEntity *pTestEnt = m_hAttachEntity[i].Get();
				if ( pTestEnt )
				{
					if ( pTestEnt == this )
					{
						mins = maxs = GetAbsOrigin();
					}
					else
					{
						// We do this so we don't have to calculate attachments (and do expensive bone-setup calculations) on our attachments.
						Vector attMins, attMaxs;
						m_hAttachEntity[i]->GetRenderBoundsWorldspace( attMins, attMaxs );

						mins = mins.Min( attMins );
						mins = mins.Min( attMaxs );
						
						maxs = maxs.Max( attMins );
						maxs = maxs.Max( attMaxs );
					}
					
					//ASSERT_COORD( mins );
					//ASSERT_COORD( maxs );
				}
				else
				{
					if (i == 0)
					{
						VectorCopy( vecAbsStart, attachmentPoint );
					}
					else if (i == 1)
					{
						VectorCopy( vecAbsEnd, attachmentPoint );
					}
					else
					{
						Assert(0);
					}

					mins = mins.Min( attachmentPoint );
					maxs = maxs.Max( attachmentPoint );
				}
			}
		}
		break;

	case BEAM_POINTS:
	default:
		{
			for (int i = 0; i < 3; ++i)
			{
				if (vecAbsStart[i] < vecAbsEnd[i])
				{
					mins[i] = vecAbsStart[i];
					maxs[i] = vecAbsEnd[i];
				}
				else
				{
					mins[i] = vecAbsEnd[i];
					maxs[i] = vecAbsStart[i];
				}
			}
		}
		break;
	}

	if ( bUseExtraPoints )
	{
		mins = mins.Min( vecAbsExtra1 );
		mins = mins.Min( vecAbsExtra2 );
		maxs = maxs.Max( vecAbsExtra1 );
		maxs = maxs.Max( vecAbsExtra2 );
	}

	// Make sure the bounds are measured in *relative coords*
	Vector vecAbsOrigin = GetAbsOrigin();
	mins -= vecAbsOrigin;
	maxs -= vecAbsOrigin;
}
示例#20
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CUnitBase::FireBullets( const FireBulletsInfo_t &info )
{
	VPROF_BUDGET( "CUnitBase::FireBullets", VPROF_BUDGETGROUP_UNITS );

	static int	tracerCount;
	trace_t		tr;
	CAmmoDef*	pAmmoDef	= GetAmmoDef();
	int			nDamageType	= pAmmoDef->DamageType(info.m_iAmmoType);
	//int			nAmmoFlags	= pAmmoDef->Flags(info.m_iAmmoType);
	int iNumShots;
	float flActualDamage;

	// the default attacker is ourselves
	CBaseEntity *pAttacker = info.m_pAttacker ? info.m_pAttacker : this;

	ClearMultiDamage();
	g_MultiDamage.SetDamageType( nDamageType | DMG_NEVERGIB );

	Vector vecDir;
	Vector vecEnd;

	// Adjust spread to accuracy
	Vector vecSpread( info.m_vecSpread );
	//vecSpread.x = sin( ( (asin( info.m_vecSpread.x ) * 2.0f) * m_fAccuracy ) / 2.0f );
	//vecSpread.y = sin( ( (asin( info.m_vecSpread.y ) * 2.0f) * m_fAccuracy ) / 2.0f );
	//vecSpread.z = sin( ( (asin( info.m_vecSpread.z ) * 2.0f) * m_fAccuracy ) / 2.0f );

	// Skip multiple entities when tracing
	CWarsBulletsFilter traceFilter( this, COLLISION_GROUP_NONE );
	traceFilter.SetPassEntity( this ); // Standard pass entity for THIS so that it can be easily removed from the list after passing through a portal
	traceFilter.AddEntityToIgnore( info.m_pAdditionalIgnoreEnt );

	CShotManipulator Manipulator( info.m_vecDirShooting );

	iNumShots = info.m_iShots;
	flActualDamage = info.m_flDamage;
	if ( flActualDamage == 0.0 )
	{
		flActualDamage = g_pGameRules->GetAmmoDamage( pAttacker, tr.m_pEnt, info.m_iAmmoType );
	}

	flActualDamage *= m_fAccuracy; // Pretty much a damage modifier

	for (int iShot = 0; iShot < iNumShots; iShot++)
	{
		//vecDir = info.m_vecDirShooting;
		vecDir = Manipulator.ApplySpread( vecSpread );

		vecEnd = info.m_vecSrc + vecDir * info.m_flDistance;

		AI_TraceLine(info.m_vecSrc, vecEnd, MASK_SHOT, &traceFilter, &tr);

		if( unit_debugfirebullets.GetBool() )
		{
#ifdef CLIENT_DLL
			NDebugOverlay::Line(info.m_vecSrc, vecEnd, 255, 0, 0, 255, 0.1f);
			NDebugOverlay::Line(info.m_vecSrc, tr.endpos, 0, 255, 0, 255, 0.1f);
#else
			NDebugOverlay::Line(info.m_vecSrc, vecEnd, 255, 255, 0, 255, 0.1f);
			NDebugOverlay::Line(info.m_vecSrc, tr.endpos, 0, 255, 255, 255, 0.1f);
#endif // CLIENT_DLL
		}

		// Make sure given a valid bullet type
		if (info.m_iAmmoType == -1)
		{
			DevMsg("ERROR: Undefined ammo type!\n");
			return;
		}

		Vector vecTracerDest = tr.endpos;

		// do damage, paint decals
		if (tr.fraction != 1.0)
		{
			CTakeDamageInfo dmgInfo( pAttacker, pAttacker, flActualDamage, nDamageType );
			CalculateBulletDamageForce( &dmgInfo, info.m_iAmmoType, vecDir, tr.endpos );
			dmgInfo.ScaleDamageForce( info.m_flDamageForceScale );
			dmgInfo.SetAmmoType( info.m_iAmmoType );

			(dynamic_cast<CBaseEntity *>(tr.m_pEnt))->DispatchTraceAttack( dmgInfo, vecDir, &tr );

			// Effects only, FireBullets should be called on the client.
			// Dispatching on the server generates far too many events/data!
#ifdef CLIENT_DLL 
			DoImpactEffect( tr, nDamageType );

			Vector vecTracerSrc = vec3_origin;
			ComputeTracerStartPosition( info.m_vecSrc, &vecTracerSrc );

			trace_t Tracer;
			Tracer = tr;
			Tracer.endpos = vecTracerDest;

			MakeTracer( vecTracerSrc, Tracer, pAmmoDef->TracerType(info.m_iAmmoType) );
#endif // CLIENT_DLL
		}
	}

#ifdef GAME_DLL
	ApplyMultiDamage();
#endif // GAME_DLL
}