Fixes bug #12116
Cyborg transports now can load/unload correctly. git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@5838 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
d3881835d0
commit
807549b8e2
|
@ -2184,7 +2184,10 @@ void unloadTransporter(DROID *psTransporter, UDWORD x, UDWORD y, BOOL goingHome)
|
|||
// Inform all other players
|
||||
if (bMultiPlayer)
|
||||
{
|
||||
sendDroidDisEmbark(psDroid);
|
||||
// This isn't used for cyber transports, only 'normal' one, but that isn't used in MP games AFAIK?
|
||||
// which is why I don't know why this is here. Maybe for mod support?
|
||||
debug(LOG_ERROR,"If you see this, then notify dev team. Code: 0xDEADF00D");
|
||||
sendDroidDisEmbark(psDroid,psTransporter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
158
src/multibot.c
158
src/multibot.c
|
@ -219,8 +219,8 @@ BOOL recvDroidSecondaryAll()
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL sendDroidEmbark(const DROID* psDroid)
|
||||
// broadcast droid & transporter loading information
|
||||
BOOL sendDroidEmbark(const DROID* psDroid,const DROID* psTransporter )
|
||||
{
|
||||
if (!bMultiPlayer)
|
||||
return true;
|
||||
|
@ -228,51 +228,78 @@ BOOL sendDroidEmbark(const DROID* psDroid)
|
|||
NETbeginEncode(NET_DROIDEMBARK, NET_ALL_PLAYERS);
|
||||
{
|
||||
uint8_t player = psDroid->player;
|
||||
uint32_t droid = psDroid->id;
|
||||
uint32_t droidID = psDroid->id;
|
||||
uint32_t transporterID = psTransporter->id;
|
||||
|
||||
NETuint8_t(&player);
|
||||
NETuint32_t(&droid);
|
||||
NETuint32_t(&droidID);
|
||||
NETuint32_t(&transporterID);
|
||||
}
|
||||
return NETend();
|
||||
}
|
||||
|
||||
// receive droid & transporter loading information
|
||||
BOOL recvDroidEmbark()
|
||||
{
|
||||
DROID* psDroid;
|
||||
DROID *psDroid;
|
||||
DROID *psTransporterDroid;
|
||||
BOOL bDroidRemoved;
|
||||
|
||||
NETbeginDecode(NET_DROIDEMBARK);
|
||||
{
|
||||
uint8_t player;
|
||||
uint32_t droid;
|
||||
uint32_t droidID;
|
||||
uint32_t transporterID;
|
||||
|
||||
NETuint8_t(&player);
|
||||
NETuint32_t(&droid);
|
||||
NETuint32_t(&droidID);
|
||||
NETuint32_t(&transporterID);
|
||||
|
||||
if (!IdToDroid(droid, player, &psDroid))
|
||||
// we have to find the droid on our (local) list first.
|
||||
if (!IdToDroid(droidID, player, &psDroid))
|
||||
{
|
||||
NETend();
|
||||
// Possible it already died? (sync error?)
|
||||
debug(LOG_WARNING,"player's %d droid %d wasn't found?",player,droidID);
|
||||
return false;
|
||||
}
|
||||
if (!IdToDroid(transporterID, player, &psTransporterDroid))
|
||||
{
|
||||
NETend();
|
||||
// Possible it already died? (sync error?)
|
||||
debug(LOG_WARNING,"player's %d transport droid %d wasn't found?",player,transporterID);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (psDroid == NULL)
|
||||
{
|
||||
// how can this happen?
|
||||
return true;
|
||||
}
|
||||
|
||||
// Take it out of the world without destroying it (just removes it from the droid list)
|
||||
bDroidRemoved = droidRemove(psDroid, apsDroidLists);
|
||||
|
||||
// Init the order for when disembark
|
||||
psDroid->order = DORDER_NONE;
|
||||
setDroidTarget(psDroid, NULL);
|
||||
psDroid->psTarStats = NULL;
|
||||
|
||||
if (bDroidRemoved)
|
||||
{
|
||||
// and now we need to add it to their transporter group!
|
||||
grpJoin(psTransporterDroid->psGroup, psDroid);
|
||||
}
|
||||
else
|
||||
{
|
||||
// possible sync error?
|
||||
debug(LOG_WARNING,"Eh? Where did unit %d go? Couldn't load droid onto transporter.",droidID);
|
||||
}
|
||||
}
|
||||
NETend();
|
||||
|
||||
if (psDroid == NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Take it out of the world without destroying it
|
||||
droidRemove(psDroid, apsDroidLists);
|
||||
|
||||
// Init the order for when disembark
|
||||
psDroid->order = DORDER_NONE;
|
||||
setDroidTarget(psDroid, NULL);
|
||||
psDroid->psTarStats = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL sendDroidDisEmbark(const DROID* psDroid)
|
||||
// sending information that droid is being unloaded from a transporter
|
||||
BOOL sendDroidDisEmbark(const DROID* psDroid, const DROID* psTransporter)
|
||||
{
|
||||
if (!bMultiPlayer)
|
||||
return true;
|
||||
|
@ -280,64 +307,87 @@ BOOL sendDroidDisEmbark(const DROID* psDroid)
|
|||
NETbeginEncode(NET_DROIDDISEMBARK, NET_ALL_PLAYERS);
|
||||
{
|
||||
uint8_t player = psDroid->player;
|
||||
uint32_t droid = psDroid->id;
|
||||
uint32_t droidID = psDroid->id;
|
||||
uint32_t transporterID = psTransporter->id;
|
||||
Vector3uw pos = psDroid->pos;
|
||||
|
||||
NETuint8_t(&player);
|
||||
NETuint32_t(&droid);
|
||||
NETuint32_t(&droidID);
|
||||
NETuint32_t(&transporterID);
|
||||
NETVector3uw(&pos);
|
||||
}
|
||||
return NETend();
|
||||
}
|
||||
|
||||
// getting informaton about droid is being unloaded from a transporter
|
||||
BOOL recvDroidDisEmbark()
|
||||
{
|
||||
DROID* psDroid;
|
||||
DROID *psFoundDroid = NULL, *psTransporterDroid = NULL;
|
||||
DROID *psCheckDroid = NULL;
|
||||
|
||||
NETbeginDecode(NET_DROIDDISEMBARK);
|
||||
{
|
||||
uint8_t player;
|
||||
uint32_t droid;
|
||||
uint32_t droidID;
|
||||
uint32_t transporterID;
|
||||
Vector3uw pos;
|
||||
|
||||
NETuint8_t(&player);
|
||||
NETuint32_t(&droid);
|
||||
NETuint32_t(&droidID);
|
||||
NETuint32_t(&transporterID);
|
||||
NETVector3uw(&pos);
|
||||
|
||||
NETend();
|
||||
|
||||
if (!IdToDroid(droid, player, &psDroid))
|
||||
// find the transporter first
|
||||
if (!IdToDroid(transporterID, player, &psTransporterDroid))
|
||||
{
|
||||
// Possible it already died? (sync error?)
|
||||
debug(LOG_WARNING,"player's %d transport droid %d wasn't found?",player,transporterID);
|
||||
return false;
|
||||
}
|
||||
// we need to find the droid *in* the transporter
|
||||
psCheckDroid = psTransporterDroid ->psGroup->psList;
|
||||
while (psCheckDroid)
|
||||
{
|
||||
// is this the one we want?
|
||||
if( psCheckDroid->id == droidID)
|
||||
{
|
||||
psFoundDroid = psCheckDroid;
|
||||
break;
|
||||
}
|
||||
// not found, so check next one in *group*
|
||||
psCheckDroid = psCheckDroid->psGrpNext;
|
||||
}
|
||||
// don't continue if we couldn't find it.
|
||||
if (!psFoundDroid)
|
||||
{
|
||||
// I don't think this could ever be possible...but
|
||||
debug(LOG_ERROR,"Couldn't find droid %d to disembark from player %d's transporter?",droidID,player);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (psDroid == NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// remove it from the transporter
|
||||
grpLeave(psFoundDroid->psGroup, psFoundDroid);
|
||||
|
||||
// and add it back to the bloody droid list
|
||||
addDroid(psFoundDroid, apsDroidLists);
|
||||
|
||||
// Add it back into the world at the x/y
|
||||
psDroid->pos = pos;
|
||||
}
|
||||
psFoundDroid->pos = pos;
|
||||
|
||||
if (!droidOnMap(psDroid))
|
||||
{
|
||||
debug(LOG_ERROR, "recvDroidDisEmbark: droid not disembarked on map");
|
||||
return false;
|
||||
}
|
||||
if (!droidOnMap(psFoundDroid))
|
||||
{
|
||||
debug(LOG_ERROR,"droid %d disembarked was NOT on map?",psFoundDroid->id);
|
||||
return false;
|
||||
}
|
||||
|
||||
updateDroidOrientation(psDroid);
|
||||
|
||||
// Initialise the movement data
|
||||
initDroidMovement(psDroid);
|
||||
|
||||
// Reset droid orders
|
||||
orderDroid(psDroid, DORDER_STOP);
|
||||
gridAddObject((BASE_OBJECT *)psDroid);
|
||||
psDroid->cluster = 0;
|
||||
|
||||
addDroid(psDroid, apsDroidLists);
|
||||
updateDroidOrientation(psFoundDroid);
|
||||
|
||||
// Initialise the movement data
|
||||
initDroidMovement(psFoundDroid);
|
||||
// must add it to the grid for targeting to work
|
||||
gridAddObject((BASE_OBJECT *)psFoundDroid);
|
||||
} // NetBeginDecode
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -169,8 +169,8 @@ extern BOOL SendGroupOrderGroup(const DROID_GROUP* psGroup, DROID_ORDER order, u
|
|||
|
||||
extern BOOL sendDroidSecondary (const DROID* psDroid, SECONDARY_ORDER sec, SECONDARY_STATE state);
|
||||
extern BOOL sendDroidSecondaryAll(const DROID* psDroid);
|
||||
extern BOOL sendDroidEmbark (const DROID* psDroid);
|
||||
extern BOOL sendDroidDisEmbark (const DROID* psDroid);
|
||||
extern BOOL sendDroidEmbark (const DROID* psDroid, const DROID* psTransporter);
|
||||
extern BOOL sendDroidDisEmbark (const DROID* psDroid, const DROID* psTransporter);
|
||||
extern BOOL sendHappyVtol (const DROID* psDroid);
|
||||
|
||||
// Startup. mulitopt
|
||||
|
@ -191,7 +191,7 @@ extern BOOL addTemplate (UDWORD player,DROID_TEMPLATE *psNew);
|
|||
extern BOOL sendCheck (void); //send/recv check info
|
||||
extern BOOL sendScoreCheck (void); //score check only(frontend)
|
||||
extern BOOL sendPing (void); // allow game to request pings.
|
||||
|
||||
extern BOOL ForceDroidSync( DROID* droidToSend ); // force a sync on a droid to happen
|
||||
// multijoin
|
||||
extern void modifyResources (POWER_GEN_FUNCTION* psFunction);
|
||||
|
||||
|
|
|
@ -205,7 +205,20 @@ static DROID* pickADroid(void)
|
|||
|
||||
return pD;
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////////////////////////////
|
||||
// force a droid sync
|
||||
// We need to update the droid in question ASAP, to prevent 'lost' droids until
|
||||
// the next 'real' update is done.
|
||||
BOOL ForceDroidSync( DROID* droidToSend )
|
||||
{
|
||||
uint8_t count = 1; // *always* one
|
||||
if(!droidToSend) return false;
|
||||
debug(LOG_SYNC,"Force sync of droid %d from player %d",droidToSend->id,droidToSend->player);
|
||||
NETbeginEncode(NET_CHECK_DROID, NET_ALL_PLAYERS);
|
||||
NETuint8_t(&count);
|
||||
packageCheck(droidToSend);
|
||||
return NETend();
|
||||
}
|
||||
// ///////////////////////////////////////////////////////////////////////////
|
||||
// send a droid info packet.
|
||||
static BOOL sendDroidCheck(void)
|
||||
|
|
|
@ -794,12 +794,17 @@ void orderUpdateDroid(DROID *psDroid)
|
|||
// if in multiPlayer, only want to process if this player's droid
|
||||
if (!bMultiPlayer || psDroid->player == selectedPlayer)
|
||||
{
|
||||
transporterAddDroid((DROID *)psDroid->psTarget, psDroid);
|
||||
// save the target of current droid (the transporter)
|
||||
DROID * transporter = (DROID *)psDroid->psTarget;
|
||||
|
||||
// order the droid to stop so moveUpdateDroid does not process this unit
|
||||
orderDroid(psDroid, DORDER_STOP);
|
||||
setDroidTarget(psDroid, NULL);
|
||||
psDroid->psTarStats = NULL;
|
||||
secondarySetState(psDroid, DSO_RETURN_TO_LOC, DSS_NONE);
|
||||
// process orders *before* adding unit to transporter
|
||||
// since we remove it from the list!
|
||||
transporterAddDroid(transporter, psDroid);
|
||||
}
|
||||
}
|
||||
else if (psDroid->action == DACTION_NONE)
|
||||
|
|
|
@ -1376,71 +1376,82 @@ void transporterRemoveDroid(UDWORD id)
|
|||
}
|
||||
if (psDroid)
|
||||
{
|
||||
/*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)
|
||||
{
|
||||
psDroid->pos.x = INVALID_XY;
|
||||
psDroid->pos.y = INVALID_XY;
|
||||
}
|
||||
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);
|
||||
updateDroidOrientation(psDroid);
|
||||
//initialise the movement data
|
||||
initDroidMovement(psDroid);
|
||||
//reset droid orders
|
||||
orderDroid(psDroid, DORDER_STOP);
|
||||
gridAddObject((BASE_OBJECT *)psDroid);
|
||||
psDroid->cluster = 0;
|
||||
}
|
||||
/*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)
|
||||
{
|
||||
psDroid->pos.x = INVALID_XY;
|
||||
psDroid->pos.y = INVALID_XY;
|
||||
}
|
||||
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);
|
||||
|
||||
grpLeave(psDroid->psGroup, psDroid);
|
||||
}
|
||||
// remove it from the transporter group
|
||||
grpLeave(psDroid->psGroup, psDroid);
|
||||
|
||||
//add it back into apsDroidLists
|
||||
if (onMission)
|
||||
{
|
||||
//addDroid(psDroid, mission.apsBuiltDroids);
|
||||
addDroid(psDroid, mission.apsDroidLists);
|
||||
}
|
||||
else
|
||||
{
|
||||
addDroid(psDroid, apsDroidLists);
|
||||
}
|
||||
//add it back into apsDroidLists
|
||||
if (onMission)
|
||||
{
|
||||
//addDroid(psDroid, mission.apsBuiltDroids);
|
||||
addDroid(psDroid, mission.apsDroidLists);
|
||||
}
|
||||
else
|
||||
{
|
||||
// add the droid back onto the droid list
|
||||
addDroid(psDroid, apsDroidLists);
|
||||
//inform all other players about that
|
||||
if (bMultiPlayer)
|
||||
{
|
||||
sendDroidDisEmbark(psDroid,psCurrTransporter);
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
gridAddObject((BASE_OBJECT *)psDroid);
|
||||
psDroid->cluster = 0;
|
||||
// check if it is a commander
|
||||
if (psDroid->droidType == DROID_COMMAND)
|
||||
{
|
||||
if (grpCreate(&psGroup))
|
||||
{
|
||||
grpJoin(psGroup, psDroid);
|
||||
}
|
||||
}
|
||||
psDroid->selected = true;
|
||||
|
||||
if (psDroid->droidType == DROID_COMMAND)
|
||||
{
|
||||
if (grpCreate(&psGroup))
|
||||
{
|
||||
grpJoin(psGroup, psDroid);
|
||||
}
|
||||
}
|
||||
psDroid->selected = true;
|
||||
|
||||
if (calcRemainingCapacity(psCurrTransporter))
|
||||
{
|
||||
//make sure the button isn't flashing
|
||||
stopMissionButtonFlash(IDTRANS_LAUNCH);
|
||||
}
|
||||
if (calcRemainingCapacity(psCurrTransporter))
|
||||
{
|
||||
//make sure the button isn't flashing
|
||||
stopMissionButtonFlash(IDTRANS_LAUNCH);
|
||||
}
|
||||
}
|
||||
// we want to sync with all clients *now*.
|
||||
ForceDroidSync(psDroid);
|
||||
}
|
||||
|
||||
/*adds a droid to the current transporter via the interface*/
|
||||
|
@ -1474,8 +1485,16 @@ void intTransporterAddDroid(UDWORD id)
|
|||
/*Adds a droid to the transporter, removing it from the world */
|
||||
void transporterAddDroid(DROID *psTransporter, DROID *psDroidToAdd)
|
||||
{
|
||||
BOOL bDroidRemoved;
|
||||
BOOL bDroidRemoved;
|
||||
|
||||
ASSERT( psTransporter != NULL, "Was passed a NULL transporter" );
|
||||
ASSERT( psDroidToAdd != NULL, "Was passed a NULL droid, can't add to transporter" );
|
||||
|
||||
if (!psTransporter || !psDroidToAdd)
|
||||
{
|
||||
debug(LOG_ERROR,"We can't add the unit to the transporter!");
|
||||
return;
|
||||
}
|
||||
/* check for space */
|
||||
if (!checkTransporterSpace(psTransporter, psDroidToAdd))
|
||||
{
|
||||
|
@ -1483,24 +1502,31 @@ void transporterAddDroid(DROID *psTransporter, DROID *psDroidToAdd)
|
|||
}
|
||||
if (onMission)
|
||||
{
|
||||
// removing from droid mission list
|
||||
bDroidRemoved = droidRemove(psDroidToAdd, mission.apsDroidLists);
|
||||
}
|
||||
else
|
||||
{
|
||||
// removing from droid list
|
||||
bDroidRemoved = droidRemove(psDroidToAdd, apsDroidLists);
|
||||
|
||||
//inform all other players
|
||||
if (bMultiPlayer)
|
||||
{
|
||||
sendDroidEmbark(psDroidToAdd);
|
||||
}
|
||||
|
||||
}
|
||||
if (bDroidRemoved)
|
||||
{
|
||||
grpJoin(psTransporter->psGroup, psDroidToAdd);
|
||||
}
|
||||
//this is called by droidRemove
|
||||
if (bDroidRemoved)
|
||||
{
|
||||
// adding to transporter unit's group list
|
||||
grpJoin(psTransporter->psGroup, psDroidToAdd);
|
||||
|
||||
if (bMultiPlayer)
|
||||
{
|
||||
//inform all other players to update their local lists
|
||||
sendDroidEmbark(psDroidToAdd,psTransporter);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug(LOG_ERROR,"droid %d not found, so nothing added to transporter!",psDroidToAdd->id);
|
||||
}
|
||||
|
||||
//this is called by droidRemove
|
||||
//intRefreshScreen();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue