Target selection routine update:

- units attached to a commander will now tend to attack units that attack their commander, when they have no explicit target. The higher rank the commander has, the bigger is the chance that attacker of the commander will be attacked.

- units attached to a commander will give more priority to the targets that are already attacked by other members of the same commander group.

git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@2253 4a71c877-e1ca-e34f-864e-861f7616d084
master
Roman C 2007-07-28 16:39:20 +00:00
parent 993ae8e46f
commit 37a658ef06
2 changed files with 89 additions and 9 deletions

View File

@ -274,11 +274,12 @@ SDWORD aiBestNearestTarget(DROID *psDroid, BASE_OBJECT **ppsObj, int weapon_slot
static SDWORD targetAttackWeight(BASE_OBJECT *psTarget, BASE_OBJECT *psAttacker, SDWORD weapon_slot)
{
SDWORD targetTypeBonus=0, damageRatio=0, attackWeight=0, noTarget=-1;
DROID *targetDroid;
STRUCTURE *targetStructure;
UDWORD weaponSlot;
DROID *targetDroid=NULL,*psAttackerDroid=NULL,*psGroupDroid,*psDroid;
STRUCTURE *targetStructure=NULL;
WEAPON_EFFECT weaponEffect;
WEAPON_STATS *attackerWeapon;
BOOL bEmpWeap=FALSE;
BOOL bEmpWeap=FALSE,bCmdAttached=FALSE,bTargetingCmd=FALSE;
if(psTarget == NULL || psAttacker == NULL){
return noTarget;
@ -289,13 +290,60 @@ static SDWORD targetAttackWeight(BASE_OBJECT *psTarget, BASE_OBJECT *psAttacker,
/* Get attacker weapon effect */
if(psAttacker->type == OBJ_DROID)
{
psAttackerDroid = (DROID *)psAttacker;
attackerWeapon = (WEAPON_STATS *)(asWeaponStats +
((DROID *)psAttacker)->asWeaps[weapon_slot].nStat);
psAttackerDroid->asWeaps[weapon_slot].nStat);
//check if this droid is assigned to a commander
bCmdAttached = (psAttackerDroid->droidType != DROID_COMMAND &&
psAttackerDroid->psGroup != NULL &&
psAttackerDroid->psGroup->type == GT_COMMAND);
//find out if current target is targeting our commander
if(bCmdAttached)
{
if(psTarget->type == OBJ_DROID)
{
psDroid = (DROID *)psTarget;
//go through all enemy weapon slots
for(weaponSlot = 0; !bTargetingCmd &&
weaponSlot < ((DROID *)psTarget)->numWeaps; weaponSlot++)
{
//see if this weapon is targeting our commander
if( ( psDroid->psActionTarget[weaponSlot] ==
(BASE_OBJECT *)psAttackerDroid->psGroup->psCommander) ||
( psDroid->psTarget[weaponSlot] ==
(BASE_OBJECT *)psAttackerDroid->psGroup->psCommander) )
{
bTargetingCmd = TRUE;
}
}
}
else
{
if(psTarget->type == OBJ_STRUCTURE)
{
//go through all enemy weapons
for(weaponSlot = 0; !bTargetingCmd &&
weaponSlot < ((STRUCTURE *)psTarget)->numWeaps; weaponSlot++)
{
if( ((STRUCTURE *)psTarget)->psTarget[weaponSlot] ==
(BASE_OBJECT *)psAttackerDroid->psGroup->psCommander)
{
bTargetingCmd = TRUE;
}
}
}
}
}
}
else if(psAttacker->type == OBJ_STRUCTURE)
{
attackerWeapon = ((WEAPON_STATS *)(asWeaponStats +
((DROID *)psAttacker)->asWeaps[weapon_slot].nStat));
((STRUCTURE *)psAttacker)->asWeaps[weapon_slot].nStat));
}
else /* feature */
{
@ -431,6 +479,34 @@ static SDWORD targetAttackWeight(BASE_OBJECT *psTarget, BASE_OBJECT *psAttacker,
attackWeight /= WEIGHT_NOT_VISIBLE_F;
}
/* Commander-related criterias */
if(bCmdAttached) //attached to a commander and don't have a target assigned by some order
{
ASSERT(psAttackerDroid->psGroup->psCommander != NULL, "Commander is NULL");
//if commander is being targeted by our target, try to defend the commander
if(bTargetingCmd)
{
attackWeight += WEIGHT_CMD_RANK * ( 1 + getDroidLevel(psAttackerDroid->psGroup->psCommander));
}
//fire support - go through all droids assigned to the commander
for(psGroupDroid = psAttackerDroid->psGroup->psList;
psGroupDroid; psGroupDroid = psGroupDroid->psGrpNext)
{
for(weaponSlot = 0; weaponSlot < psGroupDroid->numWeaps; weaponSlot++)
{
//see if this droid is currently targeting current target
if(psGroupDroid->psTarget[weaponSlot] == psTarget ||
psGroupDroid->psActionTarget[weaponSlot] == psTarget)
{
//we prefer targets that are already targeted and hence will be destroyed faster
attackWeight += WEIGHT_CMD_SAME_TARGET;
}
}
}
}
return attackWeight;
}
@ -542,7 +618,7 @@ BOOL aiChooseTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget, int weapon_slot
/* find a new target */
newTargetWeight = aiBestNearestTarget((DROID *)psObj, &psTarget, weapon_slot);
/* Calculate weight of the current target of updating */
/* Calculate weight of the current target if updating */
if(bUpdateTarget){
curTargetWeight = targetAttackWeight(((DROID *)psObj)->psActionTarget[0], psObj, weapon_slot);
}
@ -590,7 +666,7 @@ BOOL aiChooseTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget, int weapon_slot
// set bCommanderBlock so that the structure does not fire until the commander
// has a target - (slow firing weapons will not be ready to fire otherwise).
bCommanderBlock = TRUE;
if (psCommander->action == DACTION_ATTACK
if (psCommander->action == DACTION_ATTACK
&& psCommander->psActionTarget[0] != NULL
&& !psCommander->psActionTarget[0]->died)
{

View File

@ -62,8 +62,12 @@
#define OLD_TARGET_THRESHOLD (WEIGHT_DIST_TILE * 4) //it only makes sense to switch target if new one is 4+ tiles closer
#define EMP_DISABLED_PENALTY_F 10 //EMP shouldn't attack emped targets again
#define EMP_STRUCT_PENALTY_F (EMP_DISABLED_PENALTY_F * 2) //EMP don't attack strzuctures, should be bigger than EMP_DISABLED_PENALTY_F
#define EMP_DISABLED_PENALTY_F 10 //EMP shouldn't attack emped targets again
#define EMP_STRUCT_PENALTY_F (EMP_DISABLED_PENALTY_F * 2) //EMP don't attack structures, should be bigger than EMP_DISABLED_PENALTY_F
//Some weights for the units attached to a commander
#define WEIGHT_CMD_RANK (WEIGHT_DIST_TILE * 4) //A single rank is as important as 4 tiles distance
#define WEIGHT_CMD_SAME_TARGET WEIGHT_DIST_TILE //Don't want this to be too high, since a commander can have many units assigned
// alliances
extern UBYTE alliances[MAX_PLAYERS][MAX_PLAYERS];