Make VTOLs finish patrolling/scouting before returning to rearm.
git-svn-id: https://warzone2100.svn.sourceforge.net/svnroot/warzone2100/trunk@8862 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
f2cf35f791
commit
8c6ca5cb91
18
src/action.c
18
src/action.c
|
@ -1012,15 +1012,23 @@ void actionUpdateDroid(DROID *psDroid)
|
|||
setDroidActionTarget(psDroid, NULL, i);
|
||||
if (i == 0)
|
||||
{
|
||||
if ( (psDroid->action != DACTION_MOVEFIRE) &&
|
||||
(psDroid->action != DACTION_TRANSPORTIN) &&
|
||||
(psDroid->action != DACTION_TRANSPORTOUT) )
|
||||
if (psDroid->action != DACTION_MOVEFIRE &&
|
||||
psDroid->action != DACTION_TRANSPORTIN &&
|
||||
psDroid->action != DACTION_TRANSPORTOUT)
|
||||
{
|
||||
psDroid->action = DACTION_NONE;
|
||||
//if Vtol - return to rearm pad
|
||||
// if VTOL - return to rearm pad if not patrolling
|
||||
if (isVtolDroid(psDroid))
|
||||
{
|
||||
moveToRearm(psDroid);
|
||||
if (psDroid->order == DORDER_PATROL)
|
||||
{
|
||||
// Back to the patrol.
|
||||
actionDroidLoc(psDroid, DACTION_MOVE, psDroid->orderX,psDroid->orderY);
|
||||
}
|
||||
else
|
||||
{
|
||||
moveToRearm(psDroid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
53
src/droid.c
53
src/droid.c
|
@ -3982,13 +3982,10 @@ BOOL isVtolDroid(const DROID* psDroid)
|
|||
&& psDroid->droidType != DROID_TRANSPORTER;
|
||||
}
|
||||
|
||||
/*returns true if a VTOL Weapon Droid which has completed all runs*/
|
||||
/* returns true if it's a VTOL weapon droid which has completed all runs */
|
||||
BOOL vtolEmpty(DROID *psDroid)
|
||||
{
|
||||
UBYTE i;
|
||||
UBYTE numVtolWeaps = 0;
|
||||
UBYTE emptyWeaps = 0;
|
||||
BOOL bEmpty = true;
|
||||
|
||||
CHECK_DROID(psDroid);
|
||||
|
||||
|
@ -4001,30 +3998,44 @@ BOOL vtolEmpty(DROID *psDroid)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (psDroid->numWeaps > 0)
|
||||
for (i = 0; i < psDroid->numWeaps; i++)
|
||||
{
|
||||
for (i = 0;i < psDroid->numWeaps;i++)
|
||||
if (asWeaponStats[psDroid->asWeaps[i].nStat].vtolAttackRuns > 0 &&
|
||||
psDroid->sMove.iAttackRuns[i] < getNumAttackRuns(psDroid, i))
|
||||
{
|
||||
if (asWeaponStats[psDroid->asWeaps[i].nStat].vtolAttackRuns > 0)
|
||||
{
|
||||
numVtolWeaps += (1 << (1 + i));
|
||||
if (psDroid->sMove.iAttackRuns[i] >= getNumAttackRuns(psDroid, i))
|
||||
{
|
||||
emptyWeaps += (1 << (1 + i));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0;i < psDroid->numWeaps;i++)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* returns true if it's a VTOL weapon droid which still has full ammo */
|
||||
BOOL vtolFull(DROID *psDroid)
|
||||
{
|
||||
UBYTE i;
|
||||
|
||||
CHECK_DROID(psDroid);
|
||||
|
||||
if (!isVtolDroid(psDroid))
|
||||
{
|
||||
if ((numVtolWeaps & (1 << (1 + i))) && !(emptyWeaps & (1 << (1 + i))))
|
||||
return false;
|
||||
}
|
||||
if (psDroid->droidType != DROID_WEAPON)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < psDroid->numWeaps; i++)
|
||||
{
|
||||
if (asWeaponStats[psDroid->asWeaps[i].nStat].vtolAttackRuns > 0 &&
|
||||
psDroid->sMove.iAttackRuns[i] > 0)
|
||||
{
|
||||
bEmpty = false;
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return bEmpty;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// true if a vtol is waiting to be rearmed by a particular rearm pad
|
||||
|
@ -4223,6 +4234,10 @@ void updateVtolAttackRun(DROID *psDroid , int weapon_slot)
|
|||
if (asWeaponStats[psDroid->asWeaps[weapon_slot].nStat].vtolAttackRuns > 0)
|
||||
{
|
||||
psDroid->sMove.iAttackRuns[weapon_slot]++;
|
||||
if (psDroid->sMove.iAttackRuns[weapon_slot] == getNumAttackRuns(psDroid, weapon_slot))
|
||||
{
|
||||
psDroid->asWeaps[weapon_slot].ammo = 0;
|
||||
}
|
||||
//quick check doesn't go over limit
|
||||
ASSERT( psDroid->sMove.iAttackRuns[weapon_slot] < UWORD_MAX, "too many attack runs");
|
||||
}
|
||||
|
|
|
@ -334,8 +334,10 @@ extern BASE_OBJECT * checkForRepairRange(DROID *psDroid,DROID *psTarget);
|
|||
|
||||
//access function
|
||||
extern BOOL isVtolDroid(const DROID* psDroid);
|
||||
/*returns true if a VTOL Weapon Droid which has completed all runs*/
|
||||
/*returns true if a VTOL weapon droid which has completed all runs*/
|
||||
extern BOOL vtolEmpty(DROID *psDroid);
|
||||
/*returns true if a VTOL weapon droid which still has full ammo*/
|
||||
extern BOOL vtolFull(DROID *psDroid);
|
||||
/*Checks a vtol for being fully armed and fully repaired to see if ready to
|
||||
leave reArm pad */
|
||||
extern BOOL vtolHappy(const DROID* psDroid);
|
||||
|
|
81
src/order.c
81
src/order.c
|
@ -521,28 +521,59 @@ void orderUpdateDroid(DROID *psDroid)
|
|||
case DORDER_SCOUT:
|
||||
case DORDER_PATROL:
|
||||
// if there is an enemy around, attack it
|
||||
if ( (psDroid->action == DACTION_MOVE) && CAN_UPDATE_NAYBORS(psDroid) &&
|
||||
(secondaryGetState(psDroid, DSO_ATTACK_LEVEL) == DSS_ALEV_ALWAYS) &&
|
||||
(aiBestNearestTarget(psDroid, &psObj, 0, NULL) >= 0) )
|
||||
if (psDroid->action == DACTION_MOVE || (psDroid->action == DACTION_NONE && isVtolDroid(psDroid)))
|
||||
{
|
||||
switch (psDroid->droidType)
|
||||
bool tooFarFromPath = false;
|
||||
if (isVtolDroid(psDroid) && psDroid->order == DORDER_PATROL)
|
||||
{
|
||||
case DROID_WEAPON:
|
||||
case DROID_CYBORG:
|
||||
case DROID_CYBORG_SUPER:
|
||||
case DROID_PERSON:
|
||||
case DROID_COMMAND:
|
||||
actionDroidObj(psDroid, DACTION_ATTACK, psObj);
|
||||
break;
|
||||
case DROID_SENSOR:
|
||||
actionDroidObj(psDroid, DACTION_OBSERVE, psObj);
|
||||
break;
|
||||
default:
|
||||
actionDroid(psDroid, DACTION_NONE);
|
||||
break;
|
||||
// Don't stray too far from the patrol path - only attack if we're near it
|
||||
// A fun algorithm to detect if we're near the path
|
||||
SDWORD deltaX, deltaY;
|
||||
deltaX = (SDWORD)psDroid->orderX - (SDWORD)psDroid->orderX2;
|
||||
deltaY = (SDWORD)psDroid->orderY - (SDWORD)psDroid->orderY2;
|
||||
if (deltaX >= deltaY &&
|
||||
(SDWORD)MIN(psDroid->orderX, psDroid->orderX2)-SCOUT_DIST <= psDroid->pos.x &&
|
||||
psDroid->pos.x <= (SDWORD)MAX(psDroid->orderX, psDroid->orderX2)+SCOUT_DIST)
|
||||
{
|
||||
tooFarFromPath = (abs(((SDWORD)psDroid->pos.x - (SDWORD)psDroid->orderX) * deltaY/deltaX +
|
||||
(SDWORD)psDroid->orderY - (SDWORD)psDroid->pos.y) > SCOUT_DIST);
|
||||
}
|
||||
if (deltaX <= deltaY &&
|
||||
(SDWORD)MIN(psDroid->orderY, psDroid->orderY2)-SCOUT_DIST <= psDroid->pos.y &&
|
||||
psDroid->pos.y <= (SDWORD)MAX(psDroid->orderY, psDroid->orderY2)+SCOUT_DIST)
|
||||
{
|
||||
tooFarFromPath = (abs(((SDWORD)psDroid->pos.y - (SDWORD)psDroid->orderY) * deltaX/deltaY +
|
||||
(SDWORD)psDroid->orderX - (SDWORD)psDroid->pos.x) > SCOUT_DIST);
|
||||
}
|
||||
else
|
||||
{
|
||||
tooFarFromPath = true;
|
||||
}
|
||||
}
|
||||
if (!tooFarFromPath &&
|
||||
CAN_UPDATE_NAYBORS(psDroid) &&
|
||||
(secondaryGetState(psDroid, DSO_ATTACK_LEVEL) == DSS_ALEV_ALWAYS) &&
|
||||
(aiBestNearestTarget(psDroid, &psObj, 0, NULL) >= 0))
|
||||
{
|
||||
switch (psDroid->droidType)
|
||||
{
|
||||
case DROID_WEAPON:
|
||||
case DROID_CYBORG:
|
||||
case DROID_CYBORG_SUPER:
|
||||
case DROID_PERSON:
|
||||
case DROID_COMMAND:
|
||||
actionDroidObj(psDroid, DACTION_ATTACK, psObj);
|
||||
break;
|
||||
case DROID_SENSOR:
|
||||
actionDroidObj(psDroid, DACTION_OBSERVE, psObj);
|
||||
break;
|
||||
default:
|
||||
actionDroid(psDroid, DACTION_NONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (psDroid->action == DACTION_NONE)
|
||||
if (psDroid->action == DACTION_NONE)
|
||||
{
|
||||
xdiff = (SDWORD)psDroid->pos.x - (SDWORD)psDroid->orderX;
|
||||
ydiff = (SDWORD)psDroid->pos.y - (SDWORD)psDroid->orderY;
|
||||
|
@ -550,19 +581,25 @@ void orderUpdateDroid(DROID *psDroid)
|
|||
{
|
||||
if (psDroid->order == DORDER_PATROL)
|
||||
{
|
||||
UDWORD tempCoord;
|
||||
// see if we have anything queued up
|
||||
if (orderDroidList(psDroid))
|
||||
{
|
||||
// started a new order, quit
|
||||
break;
|
||||
}
|
||||
if (isVtolDroid(psDroid) && !vtolFull(psDroid))
|
||||
{
|
||||
moveToRearm(psDroid);
|
||||
break;
|
||||
}
|
||||
// head back to the other point
|
||||
temp = psDroid->orderX;
|
||||
tempCoord = psDroid->orderX;
|
||||
psDroid->orderX = psDroid->orderX2;
|
||||
psDroid->orderX2 = (UWORD)temp;
|
||||
temp = psDroid->orderY;
|
||||
psDroid->orderX2 = tempCoord;
|
||||
tempCoord = psDroid->orderY;
|
||||
psDroid->orderY = psDroid->orderY2;
|
||||
psDroid->orderY2 = (UWORD)temp;
|
||||
psDroid->orderY2 = tempCoord;
|
||||
actionDroidLoc(psDroid, DACTION_MOVE, psDroid->orderX,psDroid->orderY);
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue