LTBOOL CAISenseSeeEnemyFootprint::Update(HOBJECT hStimulus, LTFLOAT fTimeDelta)
{
	if ( !IsCharacter(hStimulus) ) return LTFALSE;

	CCharacter* pChar = (CCharacter*)g_pLTServer->HandleToObject(hStimulus);

	CTList<CharFootprintInfo*>* plistFootprints = pChar->GetFootprints();

	CharFootprintInfo** ppFootprint = plistFootprints->GetItem(TLIT_FIRST);
	while ( ppFootprint && *ppFootprint )
	{
		CharFootprintInfo* pFootprint = *ppFootprint;

        if ( m_pAI->IsPositionVisibleFromEye(CAI::DefaultFilterFn, NULL, pFootprint->vPos, (m_fDistanceSqr), LTTRUE) )
		{
			React();

			// Record the Timestamp

			m_fTimestamp = pFootprint->fTimeStamp;

            return LTTRUE;
		}

		ppFootprint = plistFootprints->GetItem(TLIT_NEXT);
	}

    return LTFALSE;
}
Esempio n. 2
0
void CCharacterMgr::CallForBackupInList(BaseAI* pInTrouble, CTList<CBaseCharacter*> & list)
{
	if (!g_pServerDE || !pInTrouble) return;

	DVector vTroublePos, vHelperPos;
	g_pServerDE->GetObjectPos(pInTrouble->m_hObject, &vTroublePos);

	CBaseCharacter** pCur  = DNULL;
	BaseAI* pAI = DNULL;

	pCur = list.GetItem(TLIT_FIRST);
	while (pCur)
	{
		pAI = (BaseAI*)*pCur;
		if (pAI && !pAI->IsDead())
		{
			g_pServerDE->GetObjectPos(pAI->m_hObject, &vHelperPos);

			if (VEC_DIST(vTroublePos, vHelperPos) < 500.0f)
			{
				if (!pAI->m_hTarget)
				{
					pAI->SetNewTarget(pInTrouble->m_hLastDamager);
					pAI->TargetObject(pInTrouble->m_hLastDamager);
				}
			}
		}
		pCur = list.GetItem(TLIT_NEXT);
	}
}
Esempio n. 3
0
HOBJECT CCharacterMgr::CanHearEnemyFireInList(BaseAI* pTargeter, CTList<CBaseCharacter*> & list)
{
	CBaseCharacter** pCur  = DNULL;
	CBaseCharacter*  pChar = DNULL;

	pCur = list.GetItem(TLIT_FIRST);

	HOBJECT hObj = DNULL;
	while (pCur)
	{
		pChar = *pCur;
		if (pChar && !pChar->IsDead())
		{
			hObj = pTargeter->CanAIHearWeaponFire(pChar);
			if (hObj)
			{
				return hObj;
			}
		}
		pCur = list.GetItem(TLIT_NEXT);
	}

	return DNULL;
}
Esempio n. 4
0
void CAIMgr::UpdateAISensors()
{
	CTList<CCharacter*>* plstChars = g_pCharacterMgr->GetCharacterList( CCharacterMgr::kList_AIs );
	CCharacter** pNext;
	CAI* pCurAI;

	// No AI exist.

	if( plstChars->GetLength() == 0 )
	{
		return;
	}

	// Find the next AI to update.
	// AI update round robin, so everyone gets the opportunity to
	// do a distributed update.

	pNext = plstChars->GetItem( TLIT_FIRST );
	while( m_hNextAI && ( (*pNext)->m_hObject != m_hNextAI ) )
	{
		pNext = plstChars->GetItem( TLIT_NEXT );
	}
	if( !pNext )
	{
		pNext = plstChars->GetItem( TLIT_FIRST );
	}

	HOBJECT hFirstToUpdate = (*pNext)->m_hObject;

	// Iterate over all existing AI.

	bool bWrapped = false;
	bool bUpdateDistributedSensors = true;
	while( true )
	{
		// Bail once we have updated everyone.

		if( bWrapped )
		{
			break;
		}

		// Look ahead at the next AI to update, and flag if we've wrapped.

		pCurAI = (CAI*)*pNext;
		pNext = plstChars->GetItem( TLIT_NEXT );
		if( !pNext )
		{
			pNext = plstChars->GetItem( TLIT_FIRST );
		}
		if( (*pNext)->m_hObject == hFirstToUpdate )
		{
			bWrapped = true;
		}

		// Do not update sensors of dead AI.

		if( pCurAI->GetDestructible()->IsDead() )
		{
			continue;
		}

		// Update all AI's sensors.
		// Stop updating distributed sensors once someone has performed
		// an expensive update.

		if( pCurAI->GetAISensorMgr()->UpdateSensors( bUpdateDistributedSensors ) )
		{
#if DISTRIBUTE_SENSORS
			m_hNextAI = (*pNext)->m_hObject;
			bUpdateDistributedSensors = false;
#endif
		}
	}
}
Esempio n. 5
0
void CAIMovement::AvoidDynamicObstacles(LTVector* pvNewPos, EnumAnimMovement eMovementType)
{
	LTFLOAT fRadius = 128.f;
	LTFLOAT fRadiusSqr = fRadius * fRadius;

	LTVector vMyPos = m_pAI->GetPosition();

	// Calculate the horizontal velocity.

	LTVector vVel = *pvNewPos - vMyPos;
	vVel.y = 0.f;

	// Bail if no velocity.

	if( ( vVel.x == 0.f ) && ( vVel.z == 0.f ) )
	{
		return;
	}

	LTFLOAT fMag = vVel.Mag();

	LTVector vTotalForce(0.f, 0.f, 0.f);
	LTVector vObstaclePos;
	LTFLOAT fDistSqr;
	LTFLOAT fForce;
	LTVector vForce;

	CTList<CCharacter*>* lstChars	= LTNULL;
	CCharacter** pCur				= LTNULL;

	// Iterate over all characters in the world.

	int cCharLists = g_pCharacterMgr->GetNumCharacterLists();
	for ( int iList = 0 ; iList < cCharLists ; ++iList )
	{
		lstChars = g_pCharacterMgr->GetCharacterList(iList);

		pCur = lstChars->GetItem(TLIT_FIRST);
		while( pCur )
		{
			CCharacter* pChar = (CCharacter*)*pCur;
			pCur = lstChars->GetItem(TLIT_NEXT);

			// Ignore myself.

			if( pChar == m_pAI )
			{
				continue;
			}

			// Ignore characters that are too close to our dest.
			// The pathfinding system requires AIs to reach waypoints.

			g_pLTServer->GetObjectPos( pChar->m_hObject, &vObstaclePos );
			if( vObstaclePos.DistSqr( m_vDest ) <= fRadiusSqr )
			{
				continue;
			}

			// Only characters within radius have forces that affect me.

			fDistSqr = vObstaclePos.DistSqr( vMyPos );
			if( fDistSqr >= fRadiusSqr )
			{
				continue;
			}

			// Calculate the force vector from the obstacle to myself.

			fForce = fRadius - (LTFLOAT)sqrt( fDistSqr );
			fForce /= fRadius;
			fForce *= fForce;
			fForce *= ( 2.f * fMag );

			vForce = vMyPos - vObstaclePos;
			vForce.y = 0.f;
			vForce.Normalize();
			vForce *= fForce;

			// Accumulate the total force from all obstacles.

			vTotalForce += vForce;			
		}
	}

	// Bail if no forces are affecting me.

	if( ( vTotalForce.x == 0.f ) && ( vTotalForce.z == 0.f ) )
	{
		return;
	}

	// Calculate a new velocity vector.

	LTVector vNewVel = vVel + vTotalForce;

	// Constrain velocity so that is never deviates more than 
	// 90 degrees in either direction.  This prevents AIs from ever
	// reversing their direction when the forces are stronger than
	// the initial velocity.

	if( vNewVel.Dot( vVel ) < 0.f )
	{
		vVel.Normalize();
		LTVector vUp( 0.f, 1.f, 0.f );
		LTVector vRight = vUp.Cross( vVel );

		if( vRight.Dot( vNewVel ) < 0.f )
		{
			vNewVel = -vRight;
		}
		else {
			vNewVel = vRight;
		}
	}

	// Keep magnitude of velocity constant.

	vNewVel.Normalize();
	vNewVel *= fMag;

	// Calculate new position.
	// Bail if new position is out of volumes.
	// Bail if new position is in wrong volume.

	LTVector vNewPos = vMyPos + vNewVel;
	if( !m_pDestVolume->Inside2d( vNewPos, m_pAI->GetRadius() ) )
	{
		return;
	}


	// Move toward new position.

	*pvNewPos = vNewPos;

	if( eMovementType == kAM_Encode_GB )
	{
		m_pAI->FacePosMoving( m_pAI->GetPosition() );
	}
	else {
		m_pAI->FacePosMoving( vNewPos );
	}
}