Move sensor and ECM information into base object definition. Add convenience
functions to structures as well, and wrap some more uses. Remove the 2.1 ECM hack that limited range by a third if ECM was higher than sensor power in expectation of future work. git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@3933 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
cf36c8a87d
commit
527244e5a3
|
@ -2242,7 +2242,7 @@ void actionUpdateDroid(DROID *psDroid)
|
|||
// make sure the target is within sensor range
|
||||
xdiff = (SDWORD)psDroid->pos.x - (SDWORD)psDroid->psActionTarget[0]->pos.x;
|
||||
ydiff = (SDWORD)psDroid->pos.y - (SDWORD)psDroid->psActionTarget[0]->pos.y;
|
||||
rangeSq = droidGetSensorRange(psDroid);
|
||||
rangeSq = droidSensorRange(psDroid);
|
||||
rangeSq = rangeSq * rangeSq;
|
||||
if (!visibleObject((BASE_OBJECT *)psDroid, psDroid->psActionTarget[0]) ||
|
||||
xdiff*xdiff + ydiff*ydiff >= rangeSq)
|
||||
|
@ -2263,7 +2263,7 @@ void actionUpdateDroid(DROID *psDroid)
|
|||
// make sure the target is within sensor range
|
||||
xdiff = (SDWORD)psDroid->pos.x - (SDWORD)psDroid->psActionTarget[0]->pos.x;
|
||||
ydiff = (SDWORD)psDroid->pos.y - (SDWORD)psDroid->psActionTarget[0]->pos.y;
|
||||
rangeSq = droidGetSensorRange(psDroid);
|
||||
rangeSq = droidSensorRange(psDroid);
|
||||
rangeSq = rangeSq * rangeSq;
|
||||
if ((xdiff*xdiff + ydiff*ydiff < rangeSq) &&
|
||||
!DROID_STOPPED(psDroid))
|
||||
|
|
12
src/ai.c
12
src/ai.c
|
@ -148,7 +148,7 @@ SDWORD aiBestNearestTarget(DROID *psDroid, BASE_OBJECT **ppsObj, int weapon_slot
|
|||
{
|
||||
// make sure target is near enough
|
||||
if (dirtySqrt(psDroid->pos.x, psDroid->pos.y, tempTarget->pos.x, tempTarget->pos.y)
|
||||
< droidGetSensorRange(psDroid))
|
||||
< droidSensorRange(psDroid))
|
||||
{
|
||||
targetInQuestion = tempTarget; //consider this target
|
||||
}
|
||||
|
@ -561,7 +561,7 @@ BOOL aiChooseTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget, int weapon_slot
|
|||
STRUCTURE *psCStruct;
|
||||
DROID *psCommander;
|
||||
BOOL bCommanderBlock;
|
||||
UDWORD sensorRange;
|
||||
UDWORD sensorRange = objSensorRange(psObj);
|
||||
SECONDARY_STATE state;
|
||||
SDWORD curTargetWeight=-1,newTargetWeight;
|
||||
|
||||
|
@ -580,7 +580,6 @@ BOOL aiChooseTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget, int weapon_slot
|
|||
// Can't attack without a weapon
|
||||
return FALSE;
|
||||
}
|
||||
sensorRange = droidGetSensorRange((DROID *)psObj);
|
||||
radSquared = sensorRange * sensorRange;
|
||||
break;
|
||||
case OBJ_STRUCTURE:
|
||||
|
@ -589,7 +588,6 @@ BOOL aiChooseTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget, int weapon_slot
|
|||
// Can't attack without a weapon
|
||||
return FALSE;
|
||||
}
|
||||
sensorRange = ((STRUCTURE *)psObj)->sensorRange;
|
||||
|
||||
// increase the sensor range for AA sites
|
||||
// AA sites are defensive structures that can only shoot in the air
|
||||
|
@ -795,7 +793,7 @@ BOOL aiChooseTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget, int weapon_slot
|
|||
/* See if there is a target in range for Sensor objects*/
|
||||
BOOL aiChooseSensorTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget)
|
||||
{
|
||||
SDWORD sensorRange;
|
||||
SDWORD sensorRange = objSensorRange(psObj);
|
||||
UDWORD radSquared;
|
||||
BASE_OBJECT *psCurr,*psTemp = NULL;
|
||||
BASE_OBJECT *psTarget = NULL;
|
||||
|
@ -811,7 +809,6 @@ BOOL aiChooseSensorTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget)
|
|||
// to be used for Turret Sensors only
|
||||
return FALSE;
|
||||
}
|
||||
sensorRange = droidGetSensorRange((DROID *)psObj);
|
||||
radSquared = sensorRange * sensorRange;
|
||||
break;
|
||||
case OBJ_STRUCTURE:
|
||||
|
@ -821,11 +818,10 @@ BOOL aiChooseSensorTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget)
|
|||
// to be used for Standard and VTOL intercept Turret Sensors only
|
||||
return FALSE;
|
||||
}
|
||||
sensorRange = ((STRUCTURE *)psObj)->sensorRange;
|
||||
radSquared = sensorRange * sensorRange;
|
||||
break;
|
||||
default:
|
||||
sensorRange = radSquared = 0;
|
||||
radSquared = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,9 @@ typedef enum _object_type
|
|||
BOOL inFire; /**< TRUE if the object is in a fire */ \
|
||||
UDWORD burnStart; /**< When the object entered the fire */ \
|
||||
UDWORD burnDamage; /**< How much damage has been done since the object entered the fire */ \
|
||||
SDWORD sensorPower; /**< Active sensor power */ \
|
||||
SDWORD sensorRange; /**< Range of sensor */ \
|
||||
SDWORD ECMMod; /**< Ability to conceal oneself from sensors */ \
|
||||
UDWORD armour[NUM_HIT_SIDES][NUM_WEAPON_CLASS]
|
||||
|
||||
#define NEXTOBJ(pointerType) \
|
||||
|
|
|
@ -1803,7 +1803,7 @@ static inline void dealWithLMBDroid(DROID* psDroid, SELECTION_TYPE selection)
|
|||
"%s - Damage %d%% - ID %d - experience %f, %s - order %s - action %s - sensor range %hu power %hu - ECM %u",
|
||||
droidGetName(psDroid), 100 - PERCENT(psDroid->body, psDroid->originalBody), psDroid->id,
|
||||
psDroid->experience, getDroidLevelName(psDroid), getDroidOrderName(psDroid->order), getDroidActionName(psDroid->action),
|
||||
droidGetSensorRange(psDroid), droidGetSensorPower(psDroid), droidGetConcealment(psDroid)));
|
||||
droidSensorRange(psDroid), droidSensorPower(psDroid), droidConcealment(psDroid)));
|
||||
FeedbackClickedOn();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -4328,7 +4328,7 @@ static void showSensorRange2(BASE_OBJECT *psObj)
|
|||
else
|
||||
{
|
||||
psStruct = (STRUCTURE*)psObj;
|
||||
sensorRange = psStruct->sensorRange;
|
||||
sensorRange = structSensorRange(psStruct);
|
||||
bBuilding = TRUE;
|
||||
}
|
||||
radius = sensorRange;
|
||||
|
|
29
src/droid.h
29
src/droid.h
|
@ -406,30 +406,11 @@ BOOL droidCheckReferences(DROID *psVictimDroid);
|
|||
/** Check if droid is in a legal world position and is not on its way to drive off the map. */
|
||||
BOOL droidOnMap(DROID *psDroid);
|
||||
|
||||
static inline int droidGetSensorRange(DROID *psDroid)
|
||||
{
|
||||
return psDroid->sensorRange;
|
||||
}
|
||||
|
||||
static inline int droidGetSensorPower(DROID *psDroid)
|
||||
{
|
||||
return psDroid->sensorPower;
|
||||
}
|
||||
|
||||
static inline int droidGetJammerPower(DROID *psDroid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int droidGetJammerRange(DROID *psDroid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int droidGetConcealment(DROID *psDroid)
|
||||
{
|
||||
return psDroid->ECMMod;
|
||||
}
|
||||
#define droidSensorRange(_psDroid) objSensorRange((BASE_OBJECT *)_psDroid)
|
||||
#define droidSensorPower(_psDroid) objSensorPower((BASE_OBJECT *)_psDroid)
|
||||
#define droidJammerRange(_psDroid) objJammerRange((BASE_OBJECT *)_psDroid)
|
||||
#define droidJammerPower(_psDroid) objJammerPower((BASE_OBJECT *)_psDroid)
|
||||
#define droidConcealment(_psDroid) objConcealment((BASE_OBJECT *)_psDroid)
|
||||
|
||||
/*
|
||||
* Component stat helper functions
|
||||
|
|
|
@ -151,9 +151,6 @@ typedef struct _droid
|
|||
*/
|
||||
UDWORD weight;
|
||||
UDWORD baseSpeed; ///< the base speed dependant on propulsion type
|
||||
UDWORD sensorRange;
|
||||
UDWORD sensorPower;
|
||||
UDWORD ECMMod;
|
||||
UDWORD originalBody; ///< the original body points
|
||||
UDWORD body; ///< the current body points
|
||||
float experience;
|
||||
|
|
|
@ -373,7 +373,9 @@ FEATURE * buildFeature(FEATURE_STATS *psStats, UDWORD x, UDWORD y,BOOL FromSave)
|
|||
//psFeature->subType = psStats->subType;
|
||||
psFeature->body = psStats->body;
|
||||
psFeature->player = MAX_PLAYERS+1; //set the player out of range to avoid targeting confusions
|
||||
|
||||
psFeature->sensorRange = 0;
|
||||
psFeature->sensorPower = 0;
|
||||
psFeature->ECMMod = 0;
|
||||
psFeature->bTargetted = FALSE;
|
||||
psFeature->timeLastHit = 0;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "projectile.h"
|
||||
#include "console.h"
|
||||
#include "oprint.h"
|
||||
#include "visibility.h"
|
||||
|
||||
// print out information about a base object
|
||||
void printBaseObjInfo(BASE_OBJECT *psObj)
|
||||
|
@ -222,8 +223,8 @@ void printDroidInfo(DROID *psDroid)
|
|||
printBaseObjInfo((BASE_OBJECT *)psDroid);
|
||||
|
||||
CONPRINTF(ConsoleString,(ConsoleString," wt %d bSpeed %d sRng %d sPwr %d ECM %d bdy %d\n",
|
||||
psDroid->weight, psDroid->baseSpeed, droidGetSensorRange(psDroid),
|
||||
droidGetSensorPower(psDroid), droidGetConcealment(psDroid), psDroid->body));
|
||||
psDroid->weight, psDroid->baseSpeed, droidSensorRange(psDroid),
|
||||
droidSensorPower(psDroid), droidConcealment(psDroid), psDroid->body));
|
||||
|
||||
if (psDroid->asWeaps[0].nStat > 0)
|
||||
{
|
||||
|
|
|
@ -5925,7 +5925,7 @@ void printStructureInfo(STRUCTURE *psStructure)
|
|||
{
|
||||
CONPRINTF(ConsoleString, (ConsoleString, "%s - %d Units assigned - ID %d - sensor range %hu power %hu - ECM %u",
|
||||
getStatName(psStructure->pStructureType), countAssignedDroids(psStructure),
|
||||
psStructure->id, psStructure->sensorRange, psStructure->sensorPower, psStructure->ECMMod));
|
||||
psStructure->id, structSensorRange(psStructure), structSensorPower(psStructure), structConcealment(psStructure)));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -5947,7 +5947,7 @@ void printStructureInfo(STRUCTURE *psStructure)
|
|||
CONPRINTF(ConsoleString, (ConsoleString, "%s - %d Units assigned - ID %d - armour %d|%d - sensor range %hu power %hu - ECM %u",
|
||||
getStatName(psStructure->pStructureType), countAssignedDroids(psStructure),
|
||||
psStructure->id, psStructure->armour[0][WC_KINETIC], psStructure->armour[0][WC_HEAT],
|
||||
psStructure->sensorRange, psStructure->sensorPower, psStructure->ECMMod));
|
||||
structSensorRange(psStructure), structSensorPower(psStructure), structConcealment(psStructure)));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
|
|
|
@ -398,6 +398,12 @@ extern BOOL lasSatStructSelected(STRUCTURE *psStruct);
|
|||
|
||||
BOOL structureCheckReferences(STRUCTURE *psVictimStruct);
|
||||
|
||||
#define structSensorRange(_psObj) objSensorRange((BASE_OBJECT *)_psObj)
|
||||
#define structSensorPower(_psObj) objSensorPower((BASE_OBJECT *)_psObj)
|
||||
#define structJammerRange(_psObj) objJammerRange((BASE_OBJECT *)_psObj)
|
||||
#define structJammerPower(_psObj) objJammerPower((BASE_OBJECT *)_psObj)
|
||||
#define structConcealment(_psObj) objConcealment((BASE_OBJECT *)_psObj)
|
||||
|
||||
#define setStructureTarget(_psBuilding, _psNewTarget, _idx) _setStructureTarget(_psBuilding, _psNewTarget, _idx, __LINE__, __FUNCTION__)
|
||||
static inline void _setStructureTarget(STRUCTURE *psBuilding, BASE_OBJECT *psNewTarget, UWORD idx, int line, const char *func)
|
||||
{
|
||||
|
|
|
@ -294,18 +294,12 @@ typedef struct _structure
|
|||
* but stored here for easy access - will need to add more for variable stuff!
|
||||
*/
|
||||
//the sensor stats need to be stored since the actual sensor stat can change with research
|
||||
UWORD sensorRange;
|
||||
UWORD sensorPower;
|
||||
UWORD turretRotation[STRUCT_MAXWEAPS]; // weapon, ECM and sensor direction and pitch
|
||||
UWORD turretPitch[STRUCT_MAXWEAPS]; // weapon, ECM and sensor direction and pitch
|
||||
|
||||
UDWORD timeLastHit; //the time the structure was last attacked
|
||||
|
||||
UDWORD lastHitWeapon;
|
||||
|
||||
//the ecm power needs to be stored since the actual ecm stat can change with research
|
||||
UWORD ECMMod;
|
||||
|
||||
FUNCTIONALITY *pFunctionality; /* pointer to structure that contains fields
|
||||
necessary for functionality */
|
||||
/* The weapons on the structure */
|
||||
|
|
|
@ -259,37 +259,23 @@ BOOL visTilesPending(BASE_OBJECT *psObj)
|
|||
/* Check which tiles can be seen by an object */
|
||||
void visTilesUpdate(BASE_OBJECT *psObj)
|
||||
{
|
||||
SDWORD range;
|
||||
SDWORD range = objSensorRange(psObj);
|
||||
SDWORD ray;
|
||||
|
||||
// Get the sensor Range and power
|
||||
switch (psObj->type)
|
||||
{
|
||||
case OBJ_DROID: // Done whenever a droid is built or moves to a new tile.
|
||||
range = ((DROID *)psObj)->sensorRange;
|
||||
break;
|
||||
case OBJ_STRUCTURE: // Only done when structure initialy built.
|
||||
range = ((STRUCTURE *)psObj)->sensorRange;
|
||||
break;
|
||||
default:
|
||||
ASSERT( FALSE,
|
||||
"visTilesUpdate: visibility checking is only implemented for"
|
||||
"units and structures" );
|
||||
return;
|
||||
}
|
||||
ASSERT(psObj->type != OBJ_FEATURE, "visTilesUpdate: visibility updates are not for features!");
|
||||
|
||||
rayPlayer = psObj->player;
|
||||
|
||||
// Do the whole circle.
|
||||
for(ray=0; ray < NUM_RAYS; ray += NUM_RAYS/80)
|
||||
{
|
||||
// initialise the callback variables
|
||||
startH = psObj->pos.z + visObjHeight(psObj);
|
||||
currG = -UBYTE_MAX * GRAD_MUL;
|
||||
// Do the whole circle.
|
||||
for(ray = 0; ray < NUM_RAYS; ray += NUM_RAYS / 80)
|
||||
{
|
||||
// initialise the callback variables
|
||||
startH = psObj->pos.z + visObjHeight(psObj);
|
||||
currG = -UBYTE_MAX * GRAD_MUL;
|
||||
|
||||
// Cast the rays from the viewer
|
||||
rayCast(psObj->pos.x,psObj->pos.y,ray, range, rayTerrainCallback);
|
||||
}
|
||||
// Cast the rays from the viewer
|
||||
rayCast(psObj->pos.x, psObj->pos.y,ray, range, rayTerrainCallback);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether psViewer can see psTarget.
|
||||
|
@ -302,8 +288,7 @@ BOOL visibleObject(BASE_OBJECT *psViewer, BASE_OBJECT *psTarget)
|
|||
{
|
||||
SDWORD x,y, ray;
|
||||
SDWORD xdiff,ydiff, rangeSquared;
|
||||
SDWORD range;
|
||||
UDWORD senPower, ecmPower;
|
||||
SDWORD range = objSensorRange(psViewer);
|
||||
SDWORD tarG, top;
|
||||
STRUCTURE *psStruct;
|
||||
|
||||
|
@ -311,8 +296,6 @@ BOOL visibleObject(BASE_OBJECT *psViewer, BASE_OBJECT *psTarget)
|
|||
switch (psViewer->type)
|
||||
{
|
||||
case OBJ_DROID:
|
||||
range = ((DROID *)psViewer)->sensorRange;
|
||||
senPower = ((DROID *)psViewer)->sensorPower;
|
||||
if (((DROID*)psViewer)->droidType == DROID_COMMAND)
|
||||
{
|
||||
range = 3 * range / 2;
|
||||
|
@ -342,9 +325,6 @@ BOOL visibleObject(BASE_OBJECT *psViewer, BASE_OBJECT *psTarget)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
range = ((STRUCTURE *)psViewer)->sensorRange;
|
||||
senPower = ((STRUCTURE *)psViewer)->sensorPower;
|
||||
|
||||
// increase the sensor range for AA sites
|
||||
// AA sites are defensive structures that can only shoot in the air
|
||||
if ( (psStruct->pStructureType->type == REF_DEFENSE) &&
|
||||
|
@ -362,29 +342,10 @@ BOOL visibleObject(BASE_OBJECT *psViewer, BASE_OBJECT *psTarget)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Get the target's ecm power (if it has one)
|
||||
* or that of a nearby ECM droid.
|
||||
*/
|
||||
switch (psTarget->type)
|
||||
// Structures can be seen from further away
|
||||
if (psTarget->type == OBJ_STRUCTURE)
|
||||
{
|
||||
case OBJ_DROID:
|
||||
ecmPower = ((DROID *)psTarget)->ECMMod;
|
||||
break;
|
||||
case OBJ_STRUCTURE:
|
||||
ecmPower = ((STRUCTURE *)psTarget)->ECMMod;
|
||||
range = 4 * range / 3;
|
||||
break;
|
||||
default:
|
||||
/* No ecm so zero power */
|
||||
ecmPower = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Implement ECM by making sensor range two thirds of normal when
|
||||
* enemy's ECM rating is higher than our sensor power rating. */
|
||||
if (ecmPower > senPower)
|
||||
{
|
||||
range = range * 2 / 3;
|
||||
}
|
||||
|
||||
/* First see if the target is in sensor range */
|
||||
|
|
|
@ -96,5 +96,29 @@ static inline BOOL visObjInRange(BASE_OBJECT *psObj1, BASE_OBJECT *psObj2, SDWOR
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static inline int objSensorRange(BASE_OBJECT *psObj)
|
||||
{
|
||||
return psObj->sensorRange;
|
||||
}
|
||||
|
||||
static inline int objSensorPower(BASE_OBJECT *psObj)
|
||||
{
|
||||
return psObj->sensorPower;
|
||||
}
|
||||
|
||||
static inline int objJammerPower(BASE_OBJECT *psObj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int objJammerRange(BASE_OBJECT *psObj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int objConcealment(BASE_OBJECT *psObj)
|
||||
{
|
||||
return psObj->ECMMod;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue