⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tf_shield_mobile.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}

//-----------------------------------------------------------------------------
// Set the shield angles
//-----------------------------------------------------------------------------
void CShieldMobile::SetCenterAngles( const QAngle &angles )
{
	m_ShieldEffect.SetAngles( angles );
}


void CShieldMobile::SetAngularSpringConstant( float flConstant )
{
	m_ShieldEffect.SetAngularSpringConstant( flConstant );
}


void CShieldMobile::SetFrontDistance( float flDistance )
{
	m_flFrontDistance = flDistance;
}


//-----------------------------------------------------------------------------
// Computes the shield bounding box
//-----------------------------------------------------------------------------
void CShieldMobile::ComputeBoundingBox( void )
{
	Vector mins, maxs;
	m_ShieldEffect.ComputeBounds(mins, maxs); 
	UTIL_SetSize( this, mins, maxs );
}

//-----------------------------------------------------------------------------
// Purpose: Initialize absmin & absmax to the appropriate box
//-----------------------------------------------------------------------------
void CShieldMobile::SetObjectCollisionBox( void )
{
	if ( !pev )
		return;

	SetAbsMins( GetAbsOrigin() + WorldAlignMins() );
	SetAbsMaxs( GetAbsOrigin() + WorldAlignMaxs() );
}

//-----------------------------------------------------------------------------
// Determines shield obstructions 
//-----------------------------------------------------------------------------
void CShieldMobile::DetermineObstructions( )
{
//	Vector mins, maxs;
//	m_ShieldEffect.ComputeBounds( mins, maxs );
//	VectorMin( mins, m_ShieldEffect.GetCurrentPosition(), mins );
//	VectorMax( maxs, m_ShieldEffect.GetCurrentPosition(), maxs );

//	engine->BeginTraceSubtree( mins, maxs );

	m_ShieldEffect.ComputeVertexActivity();

//	engine->EndTraceSubtree( );

}


//-----------------------------------------------------------------------------
// Called by the enumerator call in ShieldThink 
//-----------------------------------------------------------------------------
bool CShieldMobile::EnumEntity( IHandleEntity *pHandleEntity )
{
	CBaseEntity *pOther = gEntList.GetBaseEntity( pHandleEntity->GetRefEHandle() );
	if (!pOther)
		return true;

	// Blow off non-solid things
	if ( !::IsSolid(pOther->GetSolid(), pOther->GetSolidFlags()) )
		return true;

	// No model, blow it off
	if ( !pOther->GetModelIndex() )
		return true;
	
	// Blow off point-sized things....
	if ( pOther->GetSize() == vec3_origin )
		return true;

	// Don't bother if we shouldn't be colliding with this guy...
	if (!m_pEnumCtx->m_Filter.ShouldHitEntity( pOther, MASK_SOLID ))
		return true;

	// The shield is in its final position, so we're gonna have to determine the
	// point of collision by working in the space of the final position....
	// We do this by moving the obstruction by the relative movement amount...
	Vector vecStart, vecEnd;
	VectorAdd( pOther->GetAbsOrigin(), m_pEnumCtx->m_vecStartDelta, vecStart );
	VectorAdd( vecStart, m_pEnumCtx->m_vecEndDelta, vecEnd );

	Ray_t ray;
	ray.Init( vecStart, vecEnd, pOther->WorldAlignMins(), pOther->WorldAlignMaxs() );

	trace_t tr;
	if (TestCollision( ray, pOther->PhysicsSolidMaskForEntity(), tr ))
	{
		// Ok, we got a collision. Let's indicate it happened...
		// At the moment, we'll report the collision point as being on the
		// surface of the shield in its final position, which is kind of bogus...
		pOther->PhysicsImpact( this, tr );
	}

	return true;
}


//-----------------------------------------------------------------------------
// Update the shield position: 
//-----------------------------------------------------------------------------
void CShieldMobile::ShieldThink( void )
{
	CBaseEntity *owner = GetOwnerEntity();
	Vector origin;
	if ( owner )
	{
		if ( m_bAlwaysOrientToOwner )
		{
			SetCenterAngles( owner->GetAbsAngles() );
		}

		origin = owner->EyePosition();
		if ( m_flFrontDistance )
		{
			Vector vForward;
			AngleVectors( m_ShieldEffect.GetAngles(), &vForward );
			origin += vForward * m_flFrontDistance;
		}
	}
	else
	{
		Assert( 0 );
		origin = vec3_origin;
	}

	Vector vecOldOrigin = m_ShieldEffect.GetCurrentPosition();
	
	Vector vecDelta;
	VectorSubtract( origin, vecOldOrigin, vecDelta );

	float flMaxDist = 100 + m_flFrontDistance;
	if (vecDelta.LengthSqr() > flMaxDist * flMaxDist )
	{
		Teleported();
		SetNextThink( gpGlobals->curtime + 0.01f )
		return;
	}

	m_ShieldEffect.SetOrigin( origin );
	m_ShieldEffect.Simulate(gpGlobals->frametime);
	DetermineObstructions();
	SetAbsOrigin( m_ShieldEffect.GetCurrentPosition() );
	SetAbsAngles( m_ShieldEffect.GetCurrentAngles() );

	// Compute a composite bounding box surrounding the initial + new positions..
	Vector vecCompositeMins = WorldAlignMins() + vecOldOrigin;
	Vector vecCompositeMaxs = WorldAlignMaxs() + vecOldOrigin;

	ComputeBoundingBox();

	// Sweep the shield through the world + touch things it hits...
	SweepContext_t ctx( this, GetCollisionGroup() );
	VectorSubtract( GetAbsOrigin(), vecOldOrigin, ctx.m_vecStartDelta );

	if (ctx.m_vecStartDelta != vec3_origin)
	{
		// FIXME: Brutal hack; needed because IntersectRayWithTriangle misses stuff
		// especially with short rays; I'm not sure what to do about this.
		// This basically simulates a shield thickness of 15 units
		ctx.m_vecEndDelta = ctx.m_vecStartDelta;
		VectorNormalize( ctx.m_vecEndDelta );
		ctx.m_vecEndDelta *= -15.0f;

		Vector vecNewMins = WorldAlignMins() + GetAbsOrigin();
		Vector vecNewMaxs = WorldAlignMaxs() + GetAbsOrigin();
		VectorMin( vecCompositeMins, vecNewMins, vecCompositeMins );
		VectorMax( vecCompositeMaxs, vecNewMaxs, vecCompositeMaxs );

		m_pEnumCtx = &ctx;
		enginetrace->EnumerateEntities( vecCompositeMins, vecCompositeMaxs, this );
	}

	// Always think
	SetNextThink( gpGlobals->curtime + 0.01f );
}

	 
//-----------------------------------------------------------------------------
// Teleport!
//-----------------------------------------------------------------------------
void CShieldMobile::Teleported(  )
{
	CBaseEntity *owner = GetOwnerEntity();
	if (!owner)
		return;

	m_ShieldEffect.SetCurrentAngles( owner->GetAbsAngles() );

	Vector origin;
	origin = owner->EyePosition();
	if ( m_flFrontDistance )
	{
		Vector vForward;
		AngleVectors( m_ShieldEffect.GetCurrentAngles(), &vForward );
		origin += vForward * m_flFrontDistance;
	}

	m_ShieldEffect.SetCurrentPosition( origin );
}


//-----------------------------------------------------------------------------
// Purpose: Create a mobile version of the shield
//-----------------------------------------------------------------------------
CShield *CreateMobileShield( CBaseEntity *owner, float flFrontDistance )
{
	CShieldMobile *pShield = (CShieldMobile*)CreateEntityByName("shield_mobile");

	pShield->SetOwnerEntity( owner );
	pShield->SetCenterAngles( owner->GetAbsAngles() );
	pShield->SetLocalAngles( owner->GetAbsAngles() );
	pShield->SetFrontDistance( flFrontDistance );

	// Start it in the right place
	Vector vForward;
	AngleVectors( owner->GetAbsAngles(), &vForward );
	Vector vecOrigin = owner->EyePosition() + (vForward * flFrontDistance);
	UTIL_SetOrigin( pShield, vecOrigin );

	pShield->ChangeTeam( owner->GetTeamNumber() );
	pShield->SetupRecharge( shield_mobile_power.GetFloat(), shield_mobile_recharge_delay.GetFloat(), shield_mobile_recharge_amount.GetFloat(), shield_mobile_recharge_time.GetFloat() );
	pShield->Spawn();

	return pShield;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -