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-861f7616d084master
parent
993ae8e46f
commit
37a658ef06
90
src/ai.c
90
src/ai.c
|
@ -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)
|
||||
{
|
||||
|
|
8
src/ai.h
8
src/ai.h
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue