Beispiel #1
0
/* <1bd087> ../cstrike/dlls/vehicle.cpp:764 */
void CFuncVehicle::DeadEnd()
{
    CPathTrack *pTrack = m_ppath;
    ALERT(at_aiconsole, "TRAIN(%s): Dead end ", STRING(pev->targetname));

    if (pTrack != NULL)
    {
        CPathTrack *pNext;

        if (m_oldSpeed < 0)
        {
            do
            {
                pNext = pTrack->ValidPath(pTrack->GetPrevious(), TRUE);

                if (pNext != NULL)
                {
                    pTrack = pNext;
                }
            }
            while (pNext != NULL);
        }
        else
        {
            do
            {
                pNext = pTrack->ValidPath(pTrack->GetNext(), TRUE);

                if (pNext != NULL)
                {
                    pTrack = pNext;
                }
            }
            while (pNext != NULL);
        }
    }

    pev->velocity = g_vecZero;
    pev->avelocity = g_vecZero;

    if (pTrack != NULL)
    {
        ALERT(at_aiconsole, "at %s\n", STRING(pTrack->pev->targetname));

        if (!FStringNull(pTrack->pev->netname))
        {
            FireTargets(STRING(pTrack->pev->netname), this, this, USE_TOGGLE, 0);
        }
    }
    else
        ALERT(at_aiconsole, "\n");
}
Beispiel #2
0
// Assumes this is ALWAYS enabled
CPathTrack *CPathTrack :: LookAhead( Vector *origin, float dist, int move )
{
	CPathTrack *pcurrent;
	float originalDist = dist;
	
	pcurrent = this;
	Vector currentPos = *origin;

	if ( dist < 0 )		// Travelling backwards through path
	{
		dist = -dist;
		while ( dist > 0 )
		{
			Vector dir = pcurrent->pev->origin - currentPos;
			float length = dir.Length();
			if ( !length )
			{
				if ( !ValidPath(pcurrent->GetPrevious(), move) ) 	// If there is no previous node, or it's disabled, return now.
				{
					if ( !move )
						Project( pcurrent->GetNext(), pcurrent, origin, dist );
					return NULL;
				}
				pcurrent = pcurrent->GetPrevious();
			}
			else if ( length > dist )	// enough left in this path to move
			{
				*origin = currentPos + (dir * (dist / length));
				return pcurrent;
			}
			else
			{
				dist -= length;
				currentPos = pcurrent->pev->origin;
				*origin = currentPos;
				if ( !ValidPath(pcurrent->GetPrevious(), move) )	// If there is no previous node, or it's disabled, return now.
					return NULL;

				pcurrent = pcurrent->GetPrevious();
			}
		}
		*origin = currentPos;
		return pcurrent;
	}
	else 
	{
		while ( dist > 0 )
		{
			if ( !ValidPath(pcurrent->GetNext(), move) )	// If there is no next node, or it's disabled, return now.
			{
				if ( !move )
					Project( pcurrent->GetPrevious(), pcurrent, origin, dist );
				return NULL;
			}
			Vector dir = pcurrent->GetNext()->pev->origin - currentPos;
			float length = dir.Length();
			if ( !length  && !ValidPath( pcurrent->GetNext()->GetNext(), move ) )
			{
				if ( dist == originalDist ) // HACK -- up against a dead end
					return NULL;
				return pcurrent;
			}
			if ( length > dist )	// enough left in this path to move
			{
				*origin = currentPos + (dir * (dist / length));
				return pcurrent;
			}
			else
			{
				dist -= length;
				currentPos = pcurrent->GetNext()->pev->origin;
				pcurrent = pcurrent->GetNext();
				*origin = currentPos;
			}
		}
		*origin = currentPos;
	}

	return pcurrent;
}
void CTeamTrainWatcher::FireGameEvent( IGameEvent *event )
{
	if ( IsDisabled() || !m_bHandleTrainMovement )
		return;

	const char *pszEventName = event->GetName();
	if ( FStrEq( pszEventName, "path_track_passed" ) )
	{
		int iIndex = event->GetInt( "index" );
		CPathTrack *pNode = dynamic_cast< CPathTrack* >( UTIL_EntityByIndex( iIndex ) );

		if ( pNode )
		{
			bool bHandleEvent = false;
			CPathTrack *pTempNode = m_hStartNode.Get();

			// is this a node in the track we're watching?
			while ( pTempNode )
			{
				if ( pTempNode == pNode )
				{
					bHandleEvent = true;
					break;
				}

				pTempNode = pTempNode->GetNext();
			}

			if ( bHandleEvent )
			{
				// If we're receding and we've hit a node but the next node (going backwards) is disabled 
				// the train is going to stop (like at the base of a downhill section) when we start forward 
				// again we won't pass this node again so don't change our hill state based on this node.
				if ( m_bReceding )
				{
					if ( pNode->GetPrevious() && pNode->GetPrevious()->IsDisabled() )
					{
						return;
					}
				}

				int iHillType = pNode->GetHillType();
				bool bUpdate = ( m_iCurrentHillType != iHillType );

				if ( !bUpdate )
				{
					// the hill settings are the same, but are we leaving an uphill or downhill segment?
					if ( m_iCurrentHillType != HILL_TYPE_NONE )
					{
						// let's peek at the next node
						CPathTrack *pNextNode = pNode->GetNext();
						if ( m_flCurrentSpeed < 0 )
						{
							// we're going backwards
							pNextNode = pNode->GetPrevious();
						}

						if ( pNextNode )
						{
							int iNextHillType = pNextNode->GetHillType();
							if ( m_iCurrentHillType != iNextHillType )
							{
								// we're leaving an uphill or downhill segment...so reset our state until we pass the next node
								bUpdate = true;
								iHillType = HILL_TYPE_NONE;
							}
						}
					}
				}

				if ( bUpdate )
				{
					m_iCurrentHillType = iHillType;
					HandleTrainMovement();
				}
			}
		}
	}
}