Skip to content

Commit

Permalink
Allow unloading single droids from transporters again.
Browse files Browse the repository at this point in the history
Fixes ticket:2617.
  • Loading branch information
Cyp committed Nov 18, 2011
1 parent a6c3079 commit 2a4a8a6
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 141 deletions.
8 changes: 8 additions & 0 deletions src/droid.cpp
Expand Up @@ -3226,6 +3226,14 @@ bool pickATileGen(UDWORD *x, UDWORD *y, UBYTE numIterations,
return pickATileGenThreat(x, y, numIterations, -1, -1, function);
}

bool pickATileGen(Vector2i *pos, unsigned numIterations, bool (*function)(UDWORD x, UDWORD y))
{
UDWORD x = pos->x, y = pos->y;
bool ret = pickATileGenThreat(&x, &y, numIterations, -1, -1, function);
*pos = Vector2i(x, y);
return ret;
}

/// find a tile for which the passed function will return true without any threat in the specified range
bool pickATileGenThreat(UDWORD *x, UDWORD *y, UBYTE numIterations, SDWORD threatRange,
SDWORD player, bool (*function)(UDWORD x, UDWORD y))
Expand Down
1 change: 1 addition & 0 deletions src/droid.h
Expand Up @@ -254,6 +254,7 @@ extern bool pickATile2 (UDWORD *x, UDWORD *y, UDWORD numIterations);
extern bool zonedPAT(UDWORD x, UDWORD y);
extern bool pickATileGen(UDWORD *x, UDWORD *y, UBYTE numIterations,
bool (*function)(UDWORD x, UDWORD y));
bool pickATileGen(Vector2i *pos, unsigned numIterations, bool (*function)(UDWORD x, UDWORD y));
extern bool pickATileGenThreat(UDWORD *x, UDWORD *y, UBYTE numIterations, SDWORD threatRange,
SDWORD player, bool (*function)(UDWORD x, UDWORD y));

Expand Down
6 changes: 0 additions & 6 deletions src/mission.cpp
Expand Up @@ -1900,12 +1900,6 @@ void unloadTransporter(DROID *psTransporter, UDWORD x, UDWORD y, bool goingHome)
//swap the droid and map pointers
swapMissionPointers();
}

// Inform all other players
if (bMultiMessages)
{
sendDroidDisEmbark(psDroid, psTransporter);
}
}

/* trigger script callback detailing group about to disembark */
Expand Down
44 changes: 11 additions & 33 deletions src/multibot.cpp
Expand Up @@ -42,11 +42,11 @@
#include "console.h"
#include "mapgrid.h"
#include "multirecv.h"
#include "transporter.h"

#include <vector>
#include <algorithm>

#define ANYPLAYER 99

enum SubType
{
Expand Down Expand Up @@ -254,22 +254,20 @@ bool recvDroidEmbark(NETQUEUE queue)
*
* \sa sendDroidEmbark(),recvDroidEmbark(),recvDroidDisEmbark()
*/
bool sendDroidDisEmbark(const DROID* psDroid, const DROID* psTransporter)
bool sendDroidDisembark(DROID const *psTransporter, DROID const *psDroid)
{
if (!bMultiMessages)
return true;

NETbeginEncode(NETgameQueue(selectedPlayer), GAME_DROIDDISEMBARK);
{
uint8_t player = psDroid->player;
uint32_t droidID = psDroid->id;
uint32_t transporterID = psTransporter->id;
Position pos = droidGetPrecisePosition(psDroid);
uint32_t player = psTransporter->player;
uint32_t droidId = psDroid->id;
uint32_t transportId = psTransporter->id;

NETuint8_t(&player);
NETuint32_t(&droidID);
NETuint32_t(&transporterID);
NETPosition(&pos);
NETuint32_t(&player);
NETuint32_t(&droidId);
NETuint32_t(&transportId);
}
return NETend();
}
Expand All @@ -285,15 +283,13 @@ bool recvDroidDisEmbark(NETQUEUE queue)

NETbeginDecode(queue, GAME_DROIDDISEMBARK);
{
uint8_t player;
uint32_t player;
uint32_t droidID;
uint32_t transporterID;
Position pos;

NETuint8_t(&player);
NETuint32_t(&player);
NETuint32_t(&droidID);
NETuint32_t(&transporterID);
NETPosition(&pos);

NETend();

Expand Down Expand Up @@ -326,25 +322,7 @@ bool recvDroidDisEmbark(NETQUEUE queue)
return false;
}

// remove it from the transporter
psFoundDroid->psGroup->remove(psFoundDroid);

// and add it back to the bloody droid list
addDroid(psFoundDroid, apsDroidLists);

// Add it back into the world at the x/y
droidSetPrecisePosition(psFoundDroid, pos);

if (!droidOnMap(psFoundDroid))
{
debug(LOG_ERROR, "droid %d disembarked was NOT on map?", psFoundDroid->id);
return false;
}

updateDroidOrientation(psFoundDroid);

// Initialise the movement data
initDroidMovement(psFoundDroid);
transporterRemoveDroid(psTransporterDroid, psFoundDroid, ModeImmediate);
}
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/multiplay.h
Expand Up @@ -204,7 +204,7 @@ extern bool SendCmdGroup (DROID_GROUP *psGroup, UWORD x, UWORD y, BASE_OBJECT *

extern bool sendDroidSecondary (const DROID* psDroid, SECONDARY_ORDER sec, SECONDARY_STATE state);
extern bool sendDroidEmbark (const DROID* psDroid, const DROID* psTransporter);
extern bool sendDroidDisEmbark (const DROID* psDroid, const DROID* psTransporter);
bool sendDroidDisembark(DROID const *psTransporter, DROID const *psDroid);

// Startup. mulitopt
extern bool multiTemplateSetup (void);
Expand Down
179 changes: 78 additions & 101 deletions src/transporter.cpp
Expand Up @@ -151,7 +151,6 @@ static UWORD objMajor = 0, objMinor = 0;

/*functions */
static bool intAddTransporterContents(void);
static void transporterRemoveDroid(UDWORD id);
static void setCurrentTransporter(UDWORD id);
static void intRemoveTransContentNoAnim(void);
static bool intAddTransButtonForm(void);
Expand Down Expand Up @@ -1078,16 +1077,29 @@ static void _intProcessTransporter(UDWORD id)
{
//got to have a current transporter for this to work - and can't be flying
if (psCurrTransporter != NULL && !transporterFlying(psCurrTransporter))
{
transporterRemoveDroid(id);
/*refresh the Contents list */
intAddTransporterContents();
if (onMission)
{
/*refresh the Avail list */
intAddDroidsAvailForm();
}
}
{
unsigned currID = IDTRANS_CONTSTART;
DROID *psDroid;
for (psDroid = psCurrTransporter->psGroup->psList; psDroid != NULL && psDroid != psCurrTransporter; psDroid = psDroid->psGrpNext)
{
if (currID == id)
{
break;
}
currID++;
}
if (psDroid != NULL)
{
transporterRemoveDroid(psCurrTransporter, psDroid, ModeQueue);
}
/*refresh the Contents list */
intAddTransporterContents();
if (onMission)
{
/*refresh the Avail list */
intAddDroidsAvailForm();
}
}
}
else if (id == IDTRANS_CLOSE)
{
Expand Down Expand Up @@ -1259,116 +1271,81 @@ void setCurrentTransporter(UDWORD id)
}

/*removes a droid from the group associated with the transporter*/
void transporterRemoveDroid(UDWORD id)
void transporterRemoveDroid(DROID *psTransport, DROID *psDroid, QUEUE_MODE mode)
{
DROID *psDroid, *psNext;
UDWORD currID;
UDWORD droidX, droidY;
DROID_GROUP *psGroup;
ASSERT(psTransport != NULL && psDroid != NULL, "Something NULL");

ASSERT( psCurrTransporter != NULL, "transporterRemoveUnit:can't remove units" );

if (bMultiMessages)
if (bMultiMessages && mode == ModeQueue)
{
// Not sure how to fix this...
debug(LOG_ERROR, "TODO: Can't unload single droids, sending order to unload all at once, because this code is so convoluted.");
// All at once is better than nothing...
orderDroidLoc(psCurrTransporter, DORDER_DISEMBARK, psCurrTransporter->pos.x, psCurrTransporter->pos.y, ModeQueue);
sendDroidDisembark(psTransport, psDroid);
return;
}

currID = IDTRANS_CONTSTART;
for (psDroid = psCurrTransporter->psGroup->psList; psDroid != NULL && psDroid !=
psCurrTransporter; psDroid = psNext)
/*if we're offWorld we can't pick a tile without swapping the map
pointers - can't be bothered so just do this...*/
if (onMission)
{
psNext = psDroid->psGrpNext;
if (currID == id)
{
break;
}
currID++;
psDroid->pos.x = INVALID_XY;
psDroid->pos.y = INVALID_XY;
}
if (psDroid)
else
{
/*if we're offWorld we can't pick a tile without swapping the map
pointers - can't be bothered so just do this...*/
if (onMission)
Vector2i droidPos;
if (bMultiPlayer)
{
psDroid->pos.x = INVALID_XY;
psDroid->pos.y = INVALID_XY;
//set the units next to the transporter's current location
droidPos = map_coord(psTransport->pos);
}
else
{
if (bMultiPlayer)
{
//set the units next to the transporter's current location
droidX = map_coord(psCurrTransporter->pos.x);
droidY = map_coord(psCurrTransporter->pos.y);
}
else
{
//pick a tile because save games won't remember where the droid was when it was loaded
droidX = map_coord(getLandingX(0));
droidY = map_coord(getLandingY(0));
}
if (!pickATileGen(&droidX, &droidY,LOOK_FOR_EMPTY_TILE,zonedPAT))
{
ASSERT( false, "transporterRemoveUnit: Unable to find a valid location" );
}
psDroid->pos.x = (UWORD)world_coord(droidX);
psDroid->pos.y = (UWORD)world_coord(droidY);
psDroid->pos.z = map_Height(psDroid->pos.x, psDroid->pos.y);
//pick a tile because save games won't remember where the droid was when it was loaded
droidPos = map_coord(Vector2i(getLandingX(0), getLandingY(0)));
}

// remove it from the transporter group
psDroid->psGroup->remove(psDroid);

//add it back into apsDroidLists
if (onMission)
if (!pickATileGen(&droidPos, LOOK_FOR_EMPTY_TILE, zonedPAT))
{
//addDroid(psDroid, mission.apsBuiltDroids);
addDroid(psDroid, mission.apsDroidLists);
ASSERT(false, "Unable to find a valid location");
}
else
{
// add the droid back onto the droid list
addDroid(psDroid, apsDroidLists);
psDroid->pos = Vector3i(world_coord(droidPos), map_Height(psDroid->pos));
}

//inform all other players about that
if (bMultiMessages)
{
sendDroidDisEmbark(psDroid,psCurrTransporter);
}
}
// remove it from the transporter group
psDroid->psGroup->remove(psDroid);

if (psDroid->pos.x != INVALID_XY)
{
// We can update the orders now, since everyone has been
// notified of the droid exiting the transporter
updateDroidOrientation(psDroid);
}
//initialise the movement data
initDroidMovement(psDroid);
//reset droid orders
orderDroid(psDroid, DORDER_STOP, ModeImmediate);
psDroid->cluster = 0;
// check if it is a commander
if (psDroid->droidType == DROID_COMMAND)
{
psGroup = grpCreate();
psGroup->add(psDroid);
}
psDroid->selected = true;
//add it back into apsDroidLists
if (onMission)
{
addDroid(psDroid, mission.apsDroidLists);
}
else
{
// add the droid back onto the droid list
addDroid(psDroid, apsDroidLists);
}

if (calcRemainingCapacity(psCurrTransporter))
{
//make sure the button isn't flashing
stopMissionButtonFlash(IDTRANS_LAUNCH);
}
if (psDroid->pos.x != INVALID_XY)
{
// We can update the orders now, since everyone has been
// notified of the droid exiting the transporter
updateDroidOrientation(psDroid);
}
//initialise the movement data
initDroidMovement(psDroid);
//reset droid orders
orderDroid(psDroid, DORDER_STOP, ModeImmediate);
psDroid->cluster = 0;
// check if it is a commander
if (psDroid->droidType == DROID_COMMAND)
{
DROID_GROUP *psGroup = grpCreate();
psGroup->add(psDroid);
}
psDroid->selected = true;

// we want to sync with all clients *now*.
ForceDroidSync(psDroid);
if (calcRemainingCapacity(psTransport))
{
//make sure the button isn't flashing
stopMissionButtonFlash(IDTRANS_LAUNCH);
}
}

/*adds a droid to the current transporter via the interface*/
Expand Down Expand Up @@ -1438,7 +1415,7 @@ void transporterAddDroid(DROID *psTransporter, DROID *psDroidToAdd)
// adding to transporter unit's group list
psTransporter->psGroup->add(psDroidToAdd);

if (bMultiMessages)
if (bMultiMessages && !isInSync())
{
//inform all other players to update their local lists
sendDroidEmbark(psDroidToAdd,psTransporter);
Expand Down
1 change: 1 addition & 0 deletions src/transporter.h
Expand Up @@ -46,6 +46,7 @@ extern void intProcessTransporter(UDWORD id);

/*Adds a droid to the transporter, removing it from the world*/
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);
/*calculates how much space is remaining on the transporter - allows droids to take
Expand Down

0 comments on commit 2a4a8a6

Please sign in to comment.