Skip to content

Commit

Permalink
Restore the hold, guard, and pursue secondary states.
Browse files Browse the repository at this point in the history
Partial reverts of 8fd88ed and 2bee384.

-Now prevents regular sensors from observing targets that went out
of the sensor's vision range if the secondary state was not guard.

Fixes ticket 4303.
  • Loading branch information
KJeff01 committed Mar 24, 2019
1 parent a96e324 commit 29d3696
Show file tree
Hide file tree
Showing 11 changed files with 213 additions and 30 deletions.
72 changes: 57 additions & 15 deletions src/action.cpp
Expand Up @@ -638,6 +638,8 @@ void actionUpdateDroid(DROID *psDroid)
PROPULSION_STATS *psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION];
ASSERT_OR_RETURN(, psPropStats != nullptr, "Invalid propulsion stats pointer");

bool secHoldActive = secondaryGetState(psDroid, DSO_HALTTYPE) == DSS_HALT_HOLD;

actionSanity(psDroid);

//if the droid has been attacked by an EMP weapon, it is temporarily disabled
Expand Down Expand Up @@ -1012,9 +1014,12 @@ void actionUpdateDroid(DROID *psDroid)
if (!bHasTarget)
{
BASE_OBJECT *psTarget;
if ((!isVtolDroid(psDroid)
&& (psTarget = orderStateObj(psDroid, DORDER_FIRESUPPORT))
&& psTarget->type == OBJ_STRUCTURE)
if (((order->type == DORDER_ATTACKTARGET
|| order->type == DORDER_FIRESUPPORT)
&& secHoldActive)
|| (!isVtolDroid(psDroid)
&& (psTarget = orderStateObj(psDroid, DORDER_FIRESUPPORT))
&& psTarget->type == OBJ_STRUCTURE)
|| order->type == DORDER_NONE
|| order->type == DORDER_HOLD
|| order->type == DORDER_RTR)
Expand Down Expand Up @@ -1216,7 +1221,11 @@ void actionUpdateDroid(DROID *psDroid)
//'hack' to make the droid to check the primary turrent instead of all
WEAPON_STATS *const psWeapStats = &asWeaponStats[psDroid->asWeaps[0].nStat];

if (actionInsideMinRange(psDroid, psDroid->psActionTarget[0], psWeapStats))
if (order->type == DORDER_ATTACKTARGET && secHoldActive)
{
psDroid->action = DACTION_NONE; // on hold, give up.
}
else if (actionInsideMinRange(psDroid, psDroid->psActionTarget[0], psWeapStats))
{
if (proj_Direct(psWeapStats) && order->type != DORDER_HOLD)
{
Expand Down Expand Up @@ -1518,7 +1527,7 @@ void actionUpdateDroid(DROID *psDroid)
// now do the action update
if (DROID_STOPPED(psDroid) && !actionReachedBuildPos(psDroid, psDroid->actionPos.x, psDroid->actionPos.y, ((STRUCTURE *)psDroid->psActionTarget[0])->rot.direction, order->psStats))
{
if (order->type != DORDER_HOLD)
if (order->type != DORDER_HOLD && (!secHoldActive || (secHoldActive && order->type != DORDER_NONE)))
{
objTrace(psDroid->id, "Secondary order: Go to construction site");
moveDroidToNoFormation(psDroid, psDroid->actionPos.x, psDroid->actionPos.y);
Expand Down Expand Up @@ -1572,7 +1581,7 @@ void actionUpdateDroid(DROID *psDroid)
// align the turret
actionTargetTurret(psDroid, psDroid->psActionTarget[0], &psDroid->asWeaps[0]);

if (order->type != DORDER_HOLD && !cbSensorDroid(psDroid))
if (!cbSensorDroid(psDroid))
{
// make sure the target is within sensor range
const int xdiff = (SDWORD)psDroid->pos.x - (SDWORD)psDroid->psActionTarget[0]->pos.x;
Expand All @@ -1582,8 +1591,15 @@ void actionUpdateDroid(DROID *psDroid)
if (!visibleObject(psDroid, psDroid->psActionTarget[0], false)
|| xdiff * xdiff + ydiff * ydiff >= rangeSq)
{
psDroid->action = DACTION_MOVETOOBSERVE;
moveDroidTo(psDroid, psDroid->psActionTarget[0]->pos.x, psDroid->psActionTarget[0]->pos.y);
if (secondaryGetState(psDroid, DSO_HALTTYPE) != DSS_HALT_GUARD && (order->type == DORDER_OBSERVE || order->type == DORDER_NONE || order->type == DORDER_HOLD))
{
psDroid->action = DACTION_NONE;
}
else if (!secHoldActive && order->type != DORDER_HOLD)
{
psDroid->action = DACTION_MOVETOOBSERVE;
moveDroidTo(psDroid, psDroid->psActionTarget[0]->pos.x, psDroid->psActionTarget[0]->pos.y);
}
}
}
break;
Expand Down Expand Up @@ -1642,8 +1658,16 @@ void actionUpdateDroid(DROID *psDroid)
}
if (DROID_STOPPED(psDroid) || dot(diff, diff) > rangeSq)
{
// move in range
moveDroidTo(psDroid, order->psObj->pos.x, order->psObj->pos.y);
if (secHoldActive)
{
// droid on hold, don't allow moves.
psDroid->action = DACTION_NONE;
}
else
{
// move in range
moveDroidTo(psDroid, order->psObj->pos.x,order->psObj->pos.y);
}
}
}
}
Expand Down Expand Up @@ -1866,6 +1890,7 @@ static void actionDroidBase(DROID *psDroid, DROID_ACTION_DATA *psAction)

CHECK_DROID(psDroid);

bool secHoldActive = secondaryGetState(psDroid, DSO_HALTTYPE) == DSS_HALT_HOLD;
psDroid->actionStarted = gameTime;
syncDebugDroid(psDroid, '-');
syncDebug("%d does %s", psDroid->id, getDroidActionName(psAction->action));
Expand Down Expand Up @@ -1935,7 +1960,12 @@ static void actionDroidBase(DROID *psDroid, DROID_ACTION_DATA *psAction)
psDroid->actionPos = psDroid->pos.xy;
setDroidActionTarget(psDroid, psAction->psObj, 0);

if (!isVtolDroid(psDroid) && (orderStateObj(psDroid, DORDER_FIRESUPPORT) != nullptr))
if (((order->type == DORDER_ATTACKTARGET
|| order->type == DORDER_NONE
|| order->type == DORDER_HOLD
|| order->type == DORDER_FIRESUPPORT)
&& secHoldActive)
|| (!isVtolDroid(psDroid) && (orderStateObj(psDroid, DORDER_FIRESUPPORT) != nullptr)))
{
psDroid->action = DACTION_ATTACK; // holding, try attack straightaway
}
Expand Down Expand Up @@ -2052,7 +2082,11 @@ static void actionDroidBase(DROID *psDroid, DROID_ACTION_DATA *psAction)
ASSERT_OR_RETURN(, (psDroid->psActionTarget[0] != nullptr) && (psDroid->psActionTarget[0]->type == OBJ_STRUCTURE),
"invalid target for repair order");
order->psStats = ((STRUCTURE *)psDroid->psActionTarget[0])->pStructureType;
if (order->type != DORDER_HOLD)
if (secHoldActive && (order->type == DORDER_NONE || order->type == DORDER_HOLD))
{
psDroid->action = DACTION_REPAIR;
}
else if (!secHoldActive && order->type != DORDER_HOLD)
{
psDroid->action = DACTION_MOVETOREPAIR;
moveDroidTo(psDroid, psAction->x, psAction->y);
Expand All @@ -2063,15 +2097,19 @@ static void actionDroidBase(DROID *psDroid, DROID_ACTION_DATA *psAction)
setDroidActionTarget(psDroid, psAction->psObj, 0);
psDroid->actionPos.x = psDroid->pos.x;
psDroid->actionPos.y = psDroid->pos.y;
if (order->type != DORDER_HOLD && !cbSensorDroid(psDroid))
if (secondaryGetState(psDroid, DSO_HALTTYPE) != DSS_HALT_GUARD && (order->type == DORDER_OBSERVE || order->type == DORDER_NONE || order->type == DORDER_HOLD))
{
psDroid->action = visibleObject(psDroid, psDroid->psActionTarget[0], false) ? DACTION_OBSERVE : DACTION_NONE;
}
else if (!secHoldActive && order->type != DORDER_HOLD && !cbSensorDroid(psDroid))
{
psDroid->action = DACTION_MOVETOOBSERVE;
moveDroidTo(psDroid, psDroid->psActionTarget[0]->pos.x, psDroid->psActionTarget[0]->pos.y);
}
break;
case DACTION_FIRESUPPORT:
psDroid->action = DACTION_FIRESUPPORT;
if (!isVtolDroid(psDroid) && order->psObj->type != OBJ_STRUCTURE)
if (!isVtolDroid(psDroid) && !secHoldActive && order->psObj->type != OBJ_STRUCTURE)
{
moveDroidTo(psDroid, order->psObj->pos.x, order->psObj->pos.y); // movetotarget.
}
Expand Down Expand Up @@ -2117,7 +2155,11 @@ static void actionDroidBase(DROID *psDroid, DROID_ACTION_DATA *psAction)
//initialise the action points
psDroid->actionPoints = 0;
psDroid->actionStarted = gameTime;
if (order->type != DORDER_HOLD)
if (secHoldActive && (order->type == DORDER_NONE || order->type == DORDER_HOLD))
{
psDroid->action = DACTION_DROIDREPAIR;
}
else if (!secHoldActive && order->type != DORDER_HOLD)
{
psDroid->action = DACTION_MOVETODROIDREPAIR;
moveDroidTo(psDroid, psAction->x, psAction->y);
Expand Down
5 changes: 5 additions & 0 deletions src/ai.cpp
Expand Up @@ -813,6 +813,11 @@ bool aiChooseTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget, int weapon_slot
*targetOrigin = ORIGIN_UNKNOWN;
}

if (psObj->type == OBJ_DROID && secondaryGetState((DROID *)psObj, DSO_HALTTYPE) == DSS_HALT_HOLD)
{
return false; // Not sure why we check this here...
}

ASSERT_OR_RETURN(false, (unsigned)weapon_slot < psObj->numWeaps, "Invalid weapon selected");

/* See if there is a something in range */
Expand Down
1 change: 1 addition & 0 deletions src/cmddroid.cpp
Expand Up @@ -99,6 +99,7 @@ void cmdDroidAddDroid(DROID *psCommander, DROID *psDroid)
// set the secondary states for the unit
secondarySetState(psDroid, DSO_REPAIR_LEVEL, (SECONDARY_STATE)(psCommander->secondaryOrder & DSS_REPLEV_MASK), ModeImmediate);
secondarySetState(psDroid, DSO_ATTACK_LEVEL, (SECONDARY_STATE)(psCommander->secondaryOrder & DSS_ALEV_MASK), ModeImmediate);
secondarySetState(psDroid, DSO_HALTTYPE, (SECONDARY_STATE)(psCommander->secondaryOrder & DSS_HALT_MASK), ModeImmediate);

orderDroidObj(psDroid, DORDER_GUARD, (BASE_OBJECT *)psCommander, ModeImmediate);
}
Expand Down
7 changes: 5 additions & 2 deletions src/droid.cpp
Expand Up @@ -321,8 +321,8 @@ DROID::DROID(uint32_t id, unsigned player)
, droidType(DROID_ANY)
, psGroup(nullptr)
, psGrpNext(nullptr)
, secondaryOrder(DSS_REPLEV_NEVER | DSS_ALEV_ALWAYS)
, secondaryOrderPending(DSS_REPLEV_NEVER | DSS_ALEV_ALWAYS)
, secondaryOrder(DSS_REPLEV_NEVER | DSS_ALEV_ALWAYS | DSS_HALT_GUARD)
, secondaryOrderPending(DSS_REPLEV_NEVER | DSS_ALEV_ALWAYS | DSS_HALT_GUARD)
, secondaryOrderPendingCount(0)
, action(DACTION_NONE)
, actionPos(0, 0)
Expand Down Expand Up @@ -1694,6 +1694,9 @@ DROID *reallyBuildDroid(DROID_TEMPLATE *pTemplate, Position pos, UDWORD player,

//set droid height to be above the terrain
psDroid->pos.z += TRANSPORTER_HOVER_HEIGHT;

/* reset halt secondary order from guard to hold */
secondarySetState( psDroid, DSO_HALTTYPE, DSS_HALT_HOLD );
}

if (player == selectedPlayer)
Expand Down
24 changes: 23 additions & 1 deletion src/intorder.cpp
Expand Up @@ -47,6 +47,7 @@
#define IDORDER_REPAIR_LEVEL 8020
#define IDORDER_ATTACK_LEVEL 8030
#define IDORDER_PATROL 8040
#define IDORDER_HALT_TYPE 8050
#define IDORDER_RETURN 8060
#define IDORDER_RECYCLE 8070
#define IDORDER_ASSIGN_PRODUCTION 8080
Expand Down Expand Up @@ -138,6 +139,9 @@ enum
STR_DORD_FIRE2,
STR_DORD_FIRE3,
STR_DORD_PATROL,
STR_DORD_PURSUE,
STR_DORD_GUARD,
STR_DORD_HOLDPOS,
STR_DORD_RETREPAIR,
STR_DORD_RETBASE,
STR_DORD_EMBARK,
Expand All @@ -162,6 +166,9 @@ static const char *getDORDDescription(int id)
case STR_DORD_FIRE2 : return _("Return Fire");
case STR_DORD_FIRE3 : return _("Hold Fire");
case STR_DORD_PATROL : return _("Patrol");
case STR_DORD_PURSUE : return _("Pursue");
case STR_DORD_GUARD : return _("Guard Position");
case STR_DORD_HOLDPOS : return _("Hold Position");
case STR_DORD_RETREPAIR : return _("Return For Repair");
case STR_DORD_RETBASE : return _("Return To HQ");
case STR_DORD_EMBARK : return _("Go to Transport");
Expand Down Expand Up @@ -250,6 +257,20 @@ static ORDERBUTTONS OrderButtons[NUM_ORDERS] =
{STR_DORD_CIRCLE, 0, 0},
{DSS_CIRCLE_SET, 0, 0}
},
{
ORDBUTCLASS_NORMAL,
DSO_HALTTYPE,
DSS_HALT_MASK,
ORD_BTYPE_RADIO,
ORD_JUSTIFY_CENTER | ORD_JUSTIFY_NEWLINE,
IDORDER_HALT_TYPE,
3,0,
{IMAGE_ORD_PURSUEUP, IMAGE_ORD_GUARDUP, IMAGE_ORD_HALTUP},
{IMAGE_ORD_PURSUEUP, IMAGE_ORD_GUARDUP, IMAGE_ORD_HALTUP},
{IMAGE_DES_HILIGHT, IMAGE_DES_HILIGHT, IMAGE_DES_HILIGHT},
{STR_DORD_PURSUE, STR_DORD_GUARD, STR_DORD_HOLDPOS},
{DSS_HALT_PURSUE, DSS_HALT_GUARD, DSS_HALT_HOLD}
},
{
ORDBUTCLASS_NORMAL,
DSO_RETURN_TO_LOC,
Expand Down Expand Up @@ -391,9 +412,10 @@ static std::vector<AVORDER> buildStructureOrderList(STRUCTURE *psStructure)
ASSERT_OR_RETURN(std::vector<AVORDER>(), StructIsFactory(psStructure), "BuildStructureOrderList: structure is not a factory");

//this can be hard-coded!
std::vector<AVORDER> orders(2);
std::vector<AVORDER> orders(3);
orders[0].OrderIndex = 0;//DSO_REPAIR_LEVEL;
orders[1].OrderIndex = 1;//DSO_ATTACK_LEVEL;
orders[2].OrderIndex = 2;//DSO_HALTTYPE;

return orders;
}
Expand Down
12 changes: 12 additions & 0 deletions src/keybind.cpp
Expand Up @@ -2265,6 +2265,18 @@ void kf_SetDroidOrderStop()
}
}

// --------------------------------------------------------------------------
void kf_SetDroidMoveGuard()
{
kfsf_SetSelectedDroidsState(DSO_HALTTYPE, DSS_HALT_GUARD);
}

// --------------------------------------------------------------------------
void kf_SetDroidMovePursue()
{
kfsf_SetSelectedDroidsState(DSO_HALTTYPE, DSS_HALT_PURSUE); // ASK?
}

// --------------------------------------------------------------------------
void kf_SetDroidMovePatrol()
{
Expand Down
4 changes: 4 additions & 0 deletions src/keymap.cpp
Expand Up @@ -232,6 +232,8 @@ static KeyMapSaveEntry const keyMapSaveTable[] =
{kf_SelectAllTrucks, "SelectAllTrucks"},
{kf_SetDroidOrderStop, "SetDroidOrderStop"},
{kf_SelectAllArmedVTOLs, "SelectAllArmedVTOLs"},
{kf_SetDroidMovePursue, "SetDroidMovePursue"},
{kf_SetDroidMoveGuard, "SetDroidMoveGuard"},
};

KeyMapSaveEntry const *keymapEntryByFunction(void (*function)())
Expand Down Expand Up @@ -380,8 +382,10 @@ void keyInitMappings(bool bForceDefaults)
keyAddMapping(KEYMAP_ASSIGNABLE, KEY_IGNORE, KEY_D, KEYMAP_PRESSED, kf_JumpToUnassignedUnits, N_("View Unassigned Units"));
keyAddMapping(KEYMAP_ASSIGNABLE, KEY_IGNORE, KEY_E, KEYMAP_PRESSED, kf_SetDroidAttackReturn, N_("Return Fire"));
keyAddMapping(KEYMAP_ASSIGNABLE, KEY_IGNORE, KEY_F, KEYMAP_PRESSED, kf_SetDroidAttackAtWill, N_("Fire at Will"));
keyAddMapping(KEYMAP_ASSIGNABLE, KEY_IGNORE, KEY_G, KEYMAP_PRESSED, kf_SetDroidMoveGuard, N_("Guard Position"));
keyAddMapping(KEYMAP_ASSIGNABLE, KEY_LSHIFT, KEY_H, KEYMAP_PRESSED, kf_SetDroidReturnToBase, N_("Return to HQ"));
keyAddMapping(KEYMAP_ASSIGNABLE, KEY_IGNORE, KEY_H, KEYMAP_PRESSED, kf_SetDroidOrderHold, N_("Hold Position"));
keyAddMapping(KEYMAP_ASSIGNABLE, KEY_IGNORE, KEY_P, KEYMAP_PRESSED, kf_SetDroidMovePursue, N_("Pursue"));
keyAddMapping(KEYMAP_ASSIGNABLE, KEY_IGNORE, KEY_Q, KEYMAP_PRESSED, kf_SetDroidMovePatrol, N_("Patrol"));
keyAddMapping(KEYMAP_ASSIGNABLE, KEY_IGNORE, KEY_R, KEYMAP_PRESSED, kf_SetDroidGoForRepair, N_("Return For Repair"));
keyAddMapping(KEYMAP_ASSIGNABLE, KEY_IGNORE, KEY_S, KEYMAP_PRESSED, kf_SetDroidOrderStop, N_("Stop Droid"));
Expand Down

0 comments on commit 29d3696

Please sign in to comment.