Permalink
Browse files

Make "Go to Transport" button work sensibly.

Droids now go to the nearest transport that they can fit in. Even if they're not
cyborgs. And even if there's a transporter on the other side of the map that they
could go to, instead of going to the one standing right next to them.
  • Loading branch information...
1 parent 9dcf5bd commit 2d938a0323e5c47ce4a41c9fb6c5a0d42eb9593d @Cyp Cyp committed Feb 28, 2012
Showing with 32 additions and 28 deletions.
  1. +25 −21 src/order.cpp
  2. +1 −1 src/order.h
  3. +5 −5 src/transporter.cpp
  4. +1 −1 src/transporter.h
View
@@ -2906,19 +2906,31 @@ void orderSelectedStatsTwoLocDir(UDWORD player, DROID_ORDER order, STRUCTURE_STA
/** This function runs though all player's droids to check if any of then is a transporter. Returns the transporter droid if any was found, and NULL else.*/
-DROID *FindATransporter(unsigned player)
+DROID *FindATransporter(DROID const *embarkee)
{
- DROID *psDroid;
+ bool isCyborg = cyborgDroid(embarkee) || !bMultiPlayer; // In campaign, any unit can go on a regular transporter, so consider any unit to be a cyborg.
- for (psDroid = apsDroidLists[player]; psDroid != NULL; psDroid = psDroid->psNext)
+ DROID *bestDroid = NULL;
+ unsigned bestDist = ~0u;
+
+ for (DROID *psDroid = apsDroidLists[embarkee->player]; psDroid != NULL; psDroid = psDroid->psNext)
{
- if (psDroid->droidType == DROID_TRANSPORTER || psDroid->droidType == DROID_SUPERTRANSPORTER)
+ if ((isCyborg && psDroid->droidType == DROID_TRANSPORTER) || psDroid->droidType == DROID_SUPERTRANSPORTER)
{
- return psDroid;
+ unsigned dist = iHypot(removeZ(psDroid->pos - embarkee->pos));
+ if (!checkTransporterSpace(psDroid, embarkee, false))
+ {
+ dist += 0x8000000; // Should prefer transports that aren't full.
+ }
+ if (dist < bestDist)
+ {
+ bestDroid = psDroid;
+ bestDist = dist;
+ }
}
}
- return NULL;
+ return bestDroid;
}
@@ -3293,8 +3305,8 @@ bool secondarySetState(DROID *psDroid, SECONDARY_ORDER sec, SECONDARY_STATE Stat
secondarySet = State;
break;
case DSS_RTL_TRANSPORT:
- psTransport = FindATransporter(psDroid->player);
- if (psTransport != NULL && !(bMultiPlayer && !cyborgDroid(psDroid)))
+ psTransport = FindATransporter(psDroid);
+ if (psTransport != NULL)
{
secondarySet = State;
}
@@ -3576,22 +3588,14 @@ bool secondarySetState(DROID *psDroid, SECONDARY_ORDER sec, SECONDARY_STATE Stat
CurrState |= DSS_RTL_BASE;
break;
case DSS_RTL_TRANSPORT:
- psTransport = FindATransporter(psDroid->player);
+ psTransport = FindATransporter(psDroid);
if (psTransport != NULL)
{
- // in multiPlayer can only put cyborgs onto a Transporter
- if (bMultiPlayer && !cyborgDroid(psDroid))
- {
- retVal = false;
- }
- else
+ order = DORDER_EMBARK;
+ CurrState |= DSS_RTL_TRANSPORT;
+ if (!orderState(psDroid, DORDER_EMBARK))
{
- order = DORDER_EMBARK;
- CurrState |= DSS_RTL_TRANSPORT;
- if (!orderState(psDroid, DORDER_EMBARK))
- {
- orderDroidObj(psDroid, DORDER_EMBARK, psTransport, ModeImmediate);
- }
+ orderDroidObj(psDroid, DORDER_EMBARK, psTransport, ModeImmediate);
}
}
else
View
@@ -133,7 +133,7 @@ extern void orderGroupMoralCheck(DROID_GROUP *psGroup);
extern const char* getDroidOrderName(DROID_ORDER order);
/** \brief Gets a player's transporter. */
-extern DROID *FindATransporter(unsigned player);
+DROID *FindATransporter(DROID const *embarkee);
/** \brief Checks if there are any damaged buildings to repair. */
extern BASE_OBJECT * checkForDamagedStruct(DROID *psDroid, STRUCTURE *psTarget);
View
@@ -158,7 +158,7 @@ static bool intAddTransButtonForm(void);
static bool intAddTransContentsForm(void);
static bool intAddDroidsAvailForm(void);
void intRemoveTransContent(void);
-static UDWORD transporterSpaceRequired(DROID *psDroid);
+static UDWORD transporterSpaceRequired(DROID const *psDroid);
static DROID* transInterfaceDroidList(void);
static void intTransporterAddDroid(UDWORD id);
static void intRemoveTransDroidsAvail(void);
@@ -1442,7 +1442,7 @@ void transporterAddDroid(DROID *psTransporter, DROID *psDroidToAdd)
}
/*check to see if the droid can fit on the Transporter - return true if fits*/
-bool checkTransporterSpace(DROID *psTransporter, DROID *psAssigned)
+bool checkTransporterSpace(DROID const *psTransporter, DROID const *psAssigned, bool mayFlash)
{
DROID *psDroid, *psNext;
UDWORD capacity;
@@ -1462,8 +1462,8 @@ bool checkTransporterSpace(DROID *psTransporter, DROID *psAssigned)
}
if (capacity >= transporterSpaceRequired(psAssigned))
{
- //when full flash the transporter button
- if (capacity - transporterSpaceRequired(psAssigned) == 0)
+ //when full flash the transporter button
+ if (mayFlash && capacity - transporterSpaceRequired(psAssigned) == 0)
{
flashMissionButton(IDTRANS_LAUNCH);
}
@@ -1476,7 +1476,7 @@ bool checkTransporterSpace(DROID *psTransporter, DROID *psAssigned)
}
/*returns the space the droid occupies on a transporter based on the body size*/
-UDWORD transporterSpaceRequired(DROID *psDroid)
+UDWORD transporterSpaceRequired(DROID const *psDroid)
{
UDWORD size;
View
@@ -48,7 +48,7 @@ extern void intProcessTransporter(UDWORD id);
extern void transporterAddDroid(DROID *psTransporter, DROID *psDroidToAdd);
void transporterRemoveDroid(DROID *psTransport, DROID *psDroid, QUEUE_MODE mode);
/*check to see if the droid can fit on the Transporter - return true if fits*/
-extern bool checkTransporterSpace(DROID *psTransporter, DROID *psAssigned);
+bool checkTransporterSpace(DROID const *psTransporter, DROID const *psAssigned, bool mayFlash = true);
/*calculates how much space is remaining on the transporter - allows droids to take
up different amount depending on their body size - currently all are set to one!*/
extern UDWORD calcRemainingCapacity(DROID *psTransporter);

0 comments on commit 2d938a0

Please sign in to comment.