CFuncMoveLinear ParentingFix

From Valve Developer Community
Jump to: navigation, search

Warning: This has not been fully tested. Two func_movelinear entities, one parented to the other, has been tested. These fixes were setup under the Source2007 code base.

Add the following lines to func_movelinear.h under the declaration of m_flMoveDistance:

	EHANDLE		m_hPosition1;			// Used to mark end position
	EHANDLE		m_hPosition2;			// Used to mark start position

Add these definitions to the DATADESC:

	DEFINE_KEYFIELD( m_hPosition1, FIELD_EHANDLE, "Position1" ),
	DEFINE_KEYFIELD( m_hPosition2, FIELD_EHANDLE, "Position1" ),

Locate these lines in func_movelinear.cpp:

	m_vecPosition1 = GetAbsOrigin() - (m_vecMoveDir * m_flMoveDistance * m_flStartPosition);
	m_vecPosition2 = m_vecPosition1 + (m_vecMoveDir * m_flMoveDistance);

Replace them with this:

	m_hPosition1 = CreateEntityByName( "info_target" );
	m_hPosition2 = CreateEntityByName( "info_target" );

	m_vecPosition1 = GetAbsOrigin() - (m_vecMoveDir * m_flMoveDistance * m_flStartPosition);
	m_vecPosition2 = m_vecPosition1 + (m_vecMoveDir * m_flMoveDistance);

	// Update position reference entities
	if ( m_hPosition1 != NULL )
	{
		m_hPosition1->SetAbsOrigin( m_vecPosition1 );
		if ( GetParent() )
			m_hPosition1->SetParent( GetParent() );
	}

	if ( m_hPosition2 != NULL )
	{
		m_hPosition2->SetAbsOrigin( m_vecPosition2 );
		if ( GetParent() )
			m_hPosition2->SetParent( GetParent() );
	}

Replace the function CFuncMoveLinear::MoveDone with the following code:

void CFuncMoveLinear::MoveDone( void )
{
	// Stop sounds at the next think, rather than here as another
	// SetPosition call might immediately follow the end of this move
	SetThink(&CFuncMoveLinear::StopMoveSound);
	SetNextThink( gpGlobals->curtime + 0.1f );
	BaseClass::MoveDone();

	if ( GetLocalOrigin() == m_hPosition2->GetLocalOrigin() )
	{
		m_OnFullyOpen.FireOutput( this, this );
	}
	else if ( GetLocalOrigin() == m_hPosition1->GetLocalOrigin() )
	{
		m_OnFullyClosed.FireOutput( this, this );
	}
}

Replace the functions Use, SetPosition, InputOpen, and InputClose with the following:

void CFuncMoveLinear::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
	if ( useType != USE_SET )		// Momentary buttons will pass down a float in here
		return;

	if ( value > 1.0 )
		value = 1.0;
	Vector move = m_hPosition1->GetLocalOrigin() + (value * (m_hPosition2->GetLocalOrigin() - m_hPosition1->GetLocalOrigin()));
	
	Vector delta = move - GetLocalOrigin();
	float speed = delta.Length() * 10;

	MoveTo(move, speed);
}


//-----------------------------------------------------------------------------
// Purpose: Sets the position as a value from [0..1].
//-----------------------------------------------------------------------------
void CFuncMoveLinear::SetPosition( float flPosition )
{
	Vector vTargetPos = m_hPosition1->GetLocalOrigin() + ( flPosition * (m_hPosition2->GetLocalOrigin() - m_hPosition1->GetLocalOrigin()));
	if ((vTargetPos - GetLocalOrigin()).Length() > 0.001)
	{
		MoveTo(vTargetPos, m_flSpeed);
	}
}


//------------------------------------------------------------------------------
// Purpose:
//------------------------------------------------------------------------------
void CFuncMoveLinear::InputOpen( inputdata_t &inputdata )
{
	if (GetLocalOrigin() != m_hPosition2->GetLocalOrigin())
	{
		MoveTo(m_hPosition2->GetLocalOrigin(), m_flSpeed);
	}
}


//------------------------------------------------------------------------------
// Purpose:
//------------------------------------------------------------------------------
void CFuncMoveLinear::InputClose( inputdata_t &inputdata )
{
	if (GetLocalOrigin() != m_hPosition1->GetLocalOrigin())
	{
		MoveTo(m_hPosition1->GetLocalOrigin(), m_flSpeed);
	}
}