Ejemplo n.º 1
0
// check whether a ship is in jump range of a stargate ------------------------
//
PRIVATE
int ShipInStargateJumpRange( Stargate *stargate, ShipObject *ship, geomv_t range )
{
	ASSERT( stargate != NULL );
	ASSERT( ship != NULL );

	//NOTE:
	// the ship is treated as a point for jump
	// range detection.

	Vector3 gatenormal;
	FetchZVector( stargate->ObjPosition, &gatenormal );

	Vertex3 gatepos;
	FetchTVector( stargate->ObjPosition, &gatepos );

	Vertex3 shippos;
	FetchTVector( ship->ObjPosition, &shippos );

	geomv_t shipdot  = -DOT_PRODUCT( &gatenormal, &shippos );
	geomv_t gatedot  = -DOT_PRODUCT( &gatenormal, &gatepos );
	geomv_t distance = shipdot - gatedot;

	// not in range if ship in wrong halfspace
	if ( GEOMV_NEGATIVE( distance ) ) {
		return FALSE;
	}

	// check whether inside of boundingsphere around stargate
	Vector3 stargate_ship;
	VECSUB( &stargate_ship, &shippos, &gatepos );

	geomv_t stargate_ship_len = VctLenX( &stargate_ship );
	if ( stargate_ship_len > stargate->BoundingSphere ) {
		return FALSE;
	}

	// inside the activation distance/range ?
	if ( distance < range ) {

		Vector3 shipnormal;
		FetchZVector( ship->ObjPosition, &shipnormal );

		// ship must be flying approximately head-on into the gate
		//FIXME: cone_angle like for teleporter
		geomv_t dirdot = DOT_PRODUCT( &gatenormal, &shipnormal );
		return ( dirdot > FLOAT_TO_GEOMV( 0.7f ) );
	}

	return FALSE;
}
Ejemplo n.º 2
0
// ----------------------------------------------------------------------------
//
void BOT_AI::_GoalCheck_AgentMode_Retreat()
{
    BOT_Goal* pGoal	= m_State.GetCurGoal();
	Vector3* pGoalPos = pGoal->GetGoalPosition();
	ExtraObject* pObject = NULL;
	ASSERT( pGoal != NULL );
    
	if(pGoal->GetTargetObject() == NULL) {
        if(m_pShip->CurDamage > (m_pShip->MaxDamage * 0.9)) {
	       pObject = m_Character.SelectRepairObject();
	    }
	    if(m_pShip->CurEnergy < (m_pShip->MaxEnergy * 0.1)) {
			pObject = m_Character.SelectEnergyObject();
			m_nAgentMode = AGENTMODE_RETREAT;
	    }
		if(pObject == NULL) {
            m_nAgentMode = AGENTMODE_IDLE;
            return;
         }
         pGoal->SetTargetObject(pObject);
         FetchTVector( pObject->ObjPosition, pGoalPos );
#ifdef BOT_LOGFILES
		 BOT_MsgOut("Retreat: Targetting Extra");
#endif
	}
	
	pGoalPos = pGoal->GetGoalPosition();

	// get vector to target
	Vector3 vec2Target;	
	VECSUB( &vec2Target, pGoalPos, &m_AgentPos );

	float len = VctLenX( &vec2Target );
#ifdef BOT_LOGFILES
	BOT_MsgOut( "BOT: distance to goal: %f", len );
#endif        
	if ( len < 100.0f )  {
#ifdef BOT_LOGFILES
	   BOT_MsgOut("Clearing Goal");
#endif
	   pGoal->SetTargetObject(NULL);
	   
	}

}
Ejemplo n.º 3
0
// ----------------------------------------------------------------------------
//
void BOT_AI::_GoalCheck_AgentMode_Powerup()
{
    BOT_Goal* pGoal	= m_State.GetCurGoal();
	Vector3* pGoalPos = pGoal->GetGoalPosition();
	
	ASSERT( pGoal != NULL );
    if(pGoal->GetTargetObject() == NULL) {
        ExtraObject* pObject = FetchFirstExtra();
        if(pObject == NULL) {
            m_nAgentMode = AGENTMODE_IDLE;
            return;
         }
         pGoal->SetTargetObject(pObject);
         FetchTVector( pObject->ObjPosition, pGoalPos );
#ifdef BOT_LOGFILES
         BOT_MsgOut("Targetting Extra");
#endif
	}
	
	pGoalPos = pGoal->GetGoalPosition();

	// get vector to target
	Vector3 vec2Target;	
	VECSUB( &vec2Target, pGoalPos, &m_AgentPos );

	float len = VctLenX( &vec2Target );
#ifdef BOT_LOGFILES
	BOT_MsgOut( "BOT: distance to goal: %f", len );
#endif    
	if ( len < 100.0f )  {
#ifdef BOT_LOGFILES
	   BOT_MsgOut("Clearing Goal");
	   pGoal->SetTargetObject(NULL);
#endif	   
	}
  
}
Ejemplo n.º 4
0
// scan ship objects for radar ------------------------------------------------
//
INLINE
void RadarScanShipObjects()
{
	GenObject *targetobj = NULL;

	for ( GenObject *walkobjs = FetchFirstShip(); walkobjs; ) {

		// set color for normal objects
		int rocolor = NORMAL_RADAR_OBJ_COL2;

		if ( AUX_ENABLE_DEPTHCUED_RADAR_DOTS && !AUX_ENABLE_ELITE_RADAR ) {

			Vertex3 shippos;
			FetchTVector( walkobjs->ObjPosition, &shippos );

			Vertex3 myshippos;
			FetchTVector( MyShip->ObjPosition, &myshippos );

			Vector3 dist;
			VECSUB( &dist, &shippos, &myshippos );

			geomv_t vx = dist.X;
			geomv_t vy = dist.Y;
			geomv_t vz = dist.Z;

			ABS_GEOMV( vx );
			ABS_GEOMV( vy );
			ABS_GEOMV( vz );

			int distance = 0;
			if ( ( vx > GEOMV_VANISHING ) ||
		 		 ( vy > GEOMV_VANISHING ) ||
		 		 ( vz > GEOMV_VANISHING ) ) {
				distance = GEOMV_TO_INT( VctLenX( &dist ) );
			}

			if ( distance > 4096 ) {
				rocolor = NORMAL_RADAR_OBJ_COL3;
			} else if ( distance > 2048 ) {
				rocolor = NORMAL_RADAR_OBJ_COL2;
			} else {
				rocolor = NORMAL_RADAR_OBJ_COL1;
			}
		}

		// ensure that the target object is drawn last
		if ( walkobjs->HostObjNumber == TargetObjNumber ) {

			if ( targetobj == NULL ) {
				targetobj = walkobjs;
				
				if ( ( walkobjs = walkobjs->NextObj ) == NULL ) {
					walkobjs = targetobj;
				}
				
				continue;
			}

			rocolor = TARGET_RADAR_OBJ_COL;
		}

		// depict ship's position on radar
		if ( AUX_ENABLE_ELITE_RADAR ) {
			CalcDrawEliteRadarObj( walkobjs, rocolor );
		} else {
			CalcDrawRadarObj( walkobjs, rocolor );
		}

		if ( walkobjs == targetobj ) {
			break;
		}

		if ( ( walkobjs = walkobjs->NextObj ) == NULL ) {
			walkobjs = targetobj;
		}
	}
}
Ejemplo n.º 5
0
// set the currently used goal position ---------------------------------------
//
void BOT_AI::_GoalCheck_AgentMode_Attack()
{
	//FIXME: push current goal onto goal stack
	BOT_Goal* pGoal	= m_State.GetCurGoal();
	ASSERT( pGoal != NULL );

	//FIXME: here we should also evaluate whether we pick another target

	// select a target, if none, or no ship selected as target 
	GenObject*	pTargetObject = pGoal->GetTargetObject();
	Vector3*	pGoalPos		 = pGoal->GetGoalPosition();
	if( ( pTargetObject == NULL ) || ( OBJECT_TYPE_SHIP( pTargetObject) == FALSE ) ){

		// let the character select a target
		pTargetObject = m_Character.SelectAttackTarget( m_pShip );

		// no target
		if ( pTargetObject == NULL ) {
			//FIXME: transition function
			m_nAgentMode = AGENTMODE_IDLE;
			pGoal->SetTargetObject(NULL);

#ifdef BOT_LOGFILES
			BOT_MsgOut( "switching from ATTACK to IDLE" );
#endif // BOT_LOGFILES

			return;
		}

		// set the target object
		pGoal->SetTargetObject( pTargetObject );

		// set the goal position to where the target is
		FetchTVector( pTargetObject->ObjPosition, pGoalPos );

#ifdef BOT_LOGFILES
		BOT_MsgOut( "found new ATTACK target %d", pTargetObject->HostObjNumber );
#endif // BOT_LOGFILES

	}

	Vector3	TargetPos;
	FetchTVector( pTargetObject->ObjPosition, &TargetPos );

	// get vector to target
	Vector3 vec2Target;	
	VECSUB( &vec2Target, &TargetPos, &m_AgentPos );

	float len = VctLenX( &vec2Target );
#ifdef BOT_LOGFILES
	BOT_MsgOut( "BOT: distance to target: %f", len );
#endif
#define MIN_DISTANCE_TO_TARGET 100.0f
        if ( len < 500.0F) {
			    if ( FireRepeat > 0 ) {
			       FireRepeat -= CurScreenRefFrames;
        		}
                if ( ( FireRepeat > 0 ) || ( FireDisable > 0 ) ) {
		    //do nothing!
                } else {
      
                // create laser
                   OBJ_ShootLaser( m_pShip );

                   if ( ( FireRepeat  += MyShip->FireRepeatDelay  ) <= 0 ) {
                      FireRepeat = 1;
                   }
                   if ( ( FireDisable += MyShip->FireDisableDelay ) <= 0 ) {
                      FireDisable = 1;
                   }
		}
	}
	if ( len < MIN_DISTANCE_TO_TARGET )  {
                		
		// if nearby goal, we stay where we are
		memcpy( pGoalPos, &m_AgentPos, sizeof( Vector3 ) );
               
        } else {

		// set the goal position to the position of the target
		ASSERT( pTargetObject != NULL );
		FetchTVector( pTargetObject->ObjPosition, pGoalPos );
	}

#ifdef BOT_LOGFILES
	BOT_MsgOut( "ATTACK goal is at %f %f %f", pGoalPos->X, pGoalPos->Y, pGoalPos->Z );
#endif // BOT_LOGFILES
}
Ejemplo n.º 6
0
// ----------------------------------------------------------------------------
//
void UTL_LocomotionController::ControlOjbect( object_control_s* pObjctl, Vector3* pDesiredVelocity, fixed_t _DesiredSpeed )
{
	ASSERT( pObjctl != NULL );
	ASSERT( pDesiredVelocity != NULL );

	Vector3 xDir, yDir, zDir;
	FetchXVector( pObjctl->pShip->ObjPosition, &xDir );
	FetchYVector( pObjctl->pShip->ObjPosition, &yDir );
	FetchZVector( pObjctl->pShip->ObjPosition, &zDir );

	geomv_t len = VctLenX( pDesiredVelocity );

	// stop control if desired velocity is zero 
	if ( len <= GEOMV_VANISHING ) {
		pObjctl->rot_x = 0;
		pObjctl->rot_y = 0;
		pObjctl->accel = -0.82;

#ifdef BOT_LOGFILES
		BOT_MsgOut( "ControlOjbect() got dimishing desired velocity" );
#endif // BOT_LOGFILES

		return;
	} else {
		Vector3 DesVelNorm;
		DesVelNorm.X = FLOAT_TO_GEOMV( pDesiredVelocity->X / len );
		DesVelNorm.Y = FLOAT_TO_GEOMV( pDesiredVelocity->Y / len );
		DesVelNorm.Z = FLOAT_TO_GEOMV( pDesiredVelocity->Z / len );
		
		geomv_t yaw_dot		= DOT_PRODUCT( &DesVelNorm, &xDir );
		geomv_t pitch_dot	= DOT_PRODUCT( &DesVelNorm, &yDir );
		geomv_t heading_dot = DOT_PRODUCT( &DesVelNorm, &zDir );

		float fDesiredSpeed = FIXED_TO_FLOAT( _DesiredSpeed );
		float fCurSpeed	  = FIXED_TO_FLOAT( pObjctl->pShip->CurSpeed );

		float pitch = 0;
		float yaw   = 0;

		// target is behind us
		sincosval_s fullturn;
		GetSinCos( DEG_TO_BAMS( 2 * m_nRelaxedHeadingAngle ), &fullturn );
		//if ( heading_dot < 0.0f ) {
		if ( heading_dot < -fullturn.cosval ) {

			// we must initiate a turn, if not already in a turn
			if ( !pObjctl->IsYaw() || !pObjctl->IsPitch() ) {

				// default to random
				yaw   = (float)( RAND() % 3 ) - 1;
				pitch = (float)( RAND() % 3 ) - 1;

				// steer towards goal
				if ( yaw_dot < -GEOMV_VANISHING ) {
					yaw = OCT_YAW_LEFT;
				} else if ( yaw_dot > GEOMV_VANISHING ) {
					yaw = OCT_YAW_RIGHT;
				}
				if ( pitch_dot < -GEOMV_VANISHING ) {
					pitch = OCT_PITCH_UP;
				} else if ( pitch_dot > GEOMV_VANISHING ) {
					pitch = OCT_PITCH_DOWN;
				}

			} else {
				// reuse prev. turn information
				pitch = pObjctl->rot_x;
				yaw   = pObjctl->rot_y;
			}

			// slow down, until in direction of target
		       // pObjctl->accel = heading_dot;
			//pObjctl->accel = OCT_DECELERATE;

			// also maintain min. speed during turns
			if ( fCurSpeed > m_fMinSpeedTurn ) {
				pObjctl->accel = -0.42;
			}

		} else {

			// determine accel
			if ( fDesiredSpeed > fCurSpeed ) {
				// accelerate towards target
				pObjctl->accel = OCT_ACCELERATE;
			} else if ( fDesiredSpeed < fCurSpeed ) {
				// decelerate towards target
				pObjctl->accel = OCT_DECELERATE;
			} else {
				// no accel
				pObjctl->accel = 0;
			}

			// heading must be inside of 5 degrees cone angle
			sincosval_s sincosv;
			GetSinCos( DEG_TO_BAMS( m_nRelaxedHeadingAngle ), &sincosv );
			if ( yaw_dot < -sincosv.sinval ) {
				yaw = OCT_YAW_LEFT;
			} else if ( yaw_dot > sincosv.sinval ) {
				yaw = OCT_YAW_RIGHT;
			}
			if ( pitch_dot < -sincosv.sinval ) {
				pitch = OCT_PITCH_UP;
			} else if ( pitch_dot > sincosv.sinval ) {
				pitch = OCT_PITCH_DOWN;
			}

			// if heading outside of 30 degrees cone angle, we decelerate
			GetSinCos( DEG_TO_BAMS( m_nFullSpeedHeading ), &sincosv );
			bool_t bYawOutsideHeading	= ( ( yaw_dot   < -sincosv.sinval ) || ( yaw_dot   > sincosv.sinval ) );
			bool_t bPitchOutsideHeading = ( ( pitch_dot < -sincosv.sinval ) || ( pitch_dot > sincosv.sinval ) );
			if ( bYawOutsideHeading || bPitchOutsideHeading ) {

				// also maintain min. speed during turns
				if ( fCurSpeed > min( m_fMinSpeedTurn, fDesiredSpeed ) ) {
					// decelerate towards target
					pObjctl->accel = OCT_DECELERATE;
				}
			}
		}

#ifdef BOT_LOGFILES
		BOT_MsgOut( "heading_dot: %f, yaw_dot: %f, pitch_dot: %f", heading_dot, yaw_dot, pitch_dot );
#endif // BOT_LOGFILES

		//FIXME: oct must also handle slide horiz./vert.

		pObjctl->rot_x = pitch;
		pObjctl->rot_y = yaw;
	}
}