Beispiel #1
0
/** Search the global list of sensors for a possible target for psObj. */
static BASE_OBJECT *aiSearchSensorTargets(BASE_OBJECT *psObj, int weapon_slot, WEAPON_STATS *psWStats, UWORD *targetOrigin)
{
	int		longRange = proj_GetLongRange(psWStats);
	int		tarDist = longRange * longRange;
	BOOL		foundCB = false;
	int		minDist = psWStats->minRange * psWStats->minRange;
	BASE_OBJECT	*psSensor, *psTarget = NULL;

	if (targetOrigin)
	{
		*targetOrigin = ORIGIN_UNKNOWN;
	}

	for (psSensor = apsSensorList[0]; psSensor; psSensor = psSensor->psNextFunc)
	{
		BASE_OBJECT	*psTemp = NULL;
		bool		isCB = false;
		bool		isRD = false;

		if (!aiCheckAlliances(psSensor->player, psObj->player))
		{
			continue;
		}
		else if (psSensor->type == OBJ_DROID)
		{
			DROID		*psDroid = (DROID *)psSensor;

			ASSERT_OR_RETURN(false, psDroid->droidType == DROID_SENSOR, "A non-sensor droid in a sensor list is non-sense");
			psTemp = psDroid->psTarget;
			isCB = cbSensorDroid(psDroid);
			isRD = objRadarDetector((BASE_OBJECT *)psDroid);
		}
		else if (psSensor->type == OBJ_STRUCTURE)
		{
			STRUCTURE	*psCStruct = (STRUCTURE *)psSensor;

			// skip incomplete structures
			if (psCStruct->status != SS_BUILT)
			{
				continue;
			}
			psTemp = psCStruct->psTarget[0];
			isCB = structCBSensor(psCStruct);
			isRD = objRadarDetector((BASE_OBJECT *)psCStruct);
		}
		if (!psTemp || aiObjectIsProbablyDoomed(psTemp) || !validTarget(psObj, psTemp, 0) || aiCheckAlliances(psTemp->player, psObj->player))
		{
			continue;
		}
		if (aiObjHasRange(psObj, psTemp, weapon_slot) && visibleObject(psSensor, psTemp, false))
		{
			int distSq = objPosDiffSq(psTemp->pos, psObj->pos);

			// Need to be in range, prefer closer targets or CB targets
			if ((isCB > foundCB || (isCB == foundCB && distSq < tarDist)) && distSq > minDist)
			{
				tarDist = distSq;
				psTarget = psTemp;
				if (targetOrigin)
				{
					*targetOrigin = ORIGIN_SENSOR;
				}
				
				if (isCB)
				{
					if (targetOrigin)
					{
						*targetOrigin = ORIGIN_CB_SENSOR;
					}
					foundCB = true;  // got CB target, drop everything and shoot!
				}
				else if (isRD)
				{
					if (targetOrigin)
					{
						*targetOrigin = ORIGIN_RADAR_DETECTOR;
					}
				}
			}
		}
	}
	return psTarget;
}
Beispiel #2
0
/* See if there is a target in range for Sensor objects*/
BOOL aiChooseSensorTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget)
{
	int		sensorRange = objSensorRange(psObj);
	unsigned int	radSquared = sensorRange * sensorRange;
	bool		radarDetector = objRadarDetector(psObj);

	if (!objActiveRadar(psObj) && !radarDetector)
	{
		ASSERT(false, "Only to be used for sensor turrets!");
		return false;
	}

	/* See if there is something in range */
	if (radarDetector)
	{
		BASE_OBJECT	*psCurr, *psTemp = NULL;
		int		tarDist = SDWORD_MAX;

		gridStartIterate(psObj->pos.x, psObj->pos.y, PREVIOUS_DEFAULT_GRID_SEARCH_RADIUS);
		psCurr = gridIterate();
		while (psCurr != NULL)
		{
			if ((psCurr->type == OBJ_STRUCTURE || psCurr->type == OBJ_DROID) &&
			    !aiObjectIsProbablyDoomed(psCurr))
			{
				if (!aiCheckAlliances(psCurr->player,psObj->player)
				    && objActiveRadar(psCurr))
				{
					// See if in twice *their* sensor range
					const int xdiff = psCurr->pos.x - psObj->pos.x;
					const int ydiff = psCurr->pos.y - psObj->pos.y;
					const unsigned int distSq = xdiff * xdiff + ydiff * ydiff;
					const int targetSensor = objSensorRange(psCurr) * 2;
					const unsigned int sensorSquared = targetSensor * targetSensor;

					if (distSq < sensorSquared && distSq < tarDist)
					{
						psTemp = psCurr;
						tarDist = distSq;
					}
				}
			}
			psCurr = gridIterate();
		}

		if (psTemp)
		{
			objTrace(psTemp->id, "Targetted by radar detector %d", (int)psObj->id);
			objTrace(psObj->id, "Targetting radar %d", (int)psTemp->id);
			ASSERT(!psTemp->died, "aiChooseSensorTarget gave us a dead target");
			*ppsTarget = psTemp;
			return true;
		}
	}
	else if (psObj->type == OBJ_DROID)
	{
		BASE_OBJECT	*psTarget = NULL;

		if (aiBestNearestTarget((DROID *)psObj, &psTarget, 0, NULL) >= 0)
		{
			/* See if in sensor range */
			const int xdiff = psTarget->pos.x - psObj->pos.x;
			const int ydiff = psTarget->pos.y - psObj->pos.y;
			const unsigned int distSq = xdiff * xdiff + ydiff * ydiff;

			// I do believe this will never happen, check for yourself :-)
			debug(LOG_NEVER, "Sensor droid(%d) found possible target(%d)!!!", psObj->id, psTarget->id);

			if (distSq < radSquared)
			{
				*ppsTarget = psTarget;
				return true;
			}
		}
	}
	else	// structure
	{
		BASE_OBJECT	*psCurr, *psTemp = NULL;
		int		tarDist = SDWORD_MAX;

		gridStartIterate(psObj->pos.x, psObj->pos.y, PREVIOUS_DEFAULT_GRID_SEARCH_RADIUS);
		psCurr = gridIterate();
		while (psCurr != NULL)
		{
			// Don't target features or doomed/dead objects
			if (psCurr->type != OBJ_FEATURE && !aiObjectIsProbablyDoomed(psCurr))
			{
				if (!aiCheckAlliances(psCurr->player,psObj->player) && !aiObjIsWall(psCurr))
				{
					// See if in sensor range and visible
					const int xdiff = psCurr->pos.x - psObj->pos.x;
					const int ydiff = psCurr->pos.y - psObj->pos.y;
					const unsigned int distSq = xdiff * xdiff + ydiff * ydiff;

					if (distSq < radSquared && psCurr->visible[psObj->player] && distSq < tarDist)
					{
						psTemp = psCurr;
						tarDist = distSq;
					}
				}
			}
			psCurr = gridIterate();
		}

		if (psTemp)
		{
			ASSERT(!psTemp->died, "aiChooseSensorTarget gave us a dead target");
			*ppsTarget = psTemp;
			return true;
		}
	}

	return false;
}
Beispiel #3
0
/* See if there is a target in range for Sensor objects*/
bool aiChooseSensorTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget)
{
	int		sensorRange = objSensorRange(psObj);
	unsigned int	radSquared = sensorRange * sensorRange;
	bool		radarDetector = objRadarDetector(psObj);

	if (!objActiveRadar(psObj) && !radarDetector)
	{
		ASSERT(false, "Only to be used for sensor turrets!");
		return false;
	}

	/* See if there is something in range */
	if (psObj->type == OBJ_DROID)
	{
		BASE_OBJECT	*psTarget = NULL;

		if (aiBestNearestTarget((DROID *)psObj, &psTarget, 0) >= 0)
		{
			/* See if in sensor range */
			const int xdiff = psTarget->pos.x - psObj->pos.x;
			const int ydiff = psTarget->pos.y - psObj->pos.y;
			const unsigned int distSq = xdiff * xdiff + ydiff * ydiff;

			// I do believe this will never happen, check for yourself :-)
			debug(LOG_NEVER, "Sensor droid(%d) found possible target(%d)!!!", psObj->id, psTarget->id);

			if (distSq < radSquared)
			{
				*ppsTarget = psTarget;
				return true;
			}
		}
	}
	else	// structure
	{
		BASE_OBJECT    *psTemp = NULL;
		int		tarDist = SDWORD_MAX;

		static GridList gridList;  // static to avoid allocations.
		gridList = gridStartIterate(psObj->pos.x, psObj->pos.y, objSensorRange(psObj));
		for (GridIterator gi = gridList.begin(); gi != gridList.end(); ++gi)
		{
			BASE_OBJECT *psCurr = *gi;
			// Don't target features or doomed/dead objects
			if (psCurr->type != OBJ_FEATURE && !psCurr->died && !aiObjectIsProbablyDoomed(psCurr, false))
			{
				if (!aiCheckAlliances(psCurr->player, psObj->player) && !aiObjIsWall(psCurr))
				{
					// See if in sensor range and visible
					const int xdiff = psCurr->pos.x - psObj->pos.x;
					const int ydiff = psCurr->pos.y - psObj->pos.y;
					const unsigned int distSq = xdiff * xdiff + ydiff * ydiff;

					if (distSq < radSquared && psCurr->visible[psObj->player] == UBYTE_MAX && distSq < tarDist)
					{
						psTemp = psCurr;
						tarDist = distSq;
					}
				}
			}
		}

		if (psTemp)
		{
			ASSERT(!psTemp->died, "aiChooseSensorTarget gave us a dead target");
			*ppsTarget = psTemp;
			return true;
		}
	}

	return false;
}