newnet: Make GAME_DROID synchronised, now possible to build lots of trucks and stuff without going out of synch.

master
Cyp 2010-02-22 13:29:28 +01:00
parent 8f2e94bb48
commit af28145369
13 changed files with 102 additions and 60 deletions

View File

@ -2032,7 +2032,6 @@ int NETclose(void)
{ // need SocketSet_DelSocket() as well, socket_set or tmp_socket_set?
debug(LOG_NET, "Closing bsocket %p socket %p (tcp_socket=%p)", bsocket, bsocket, tcp_socket);
//socketClose(bsocket);
NET_destroyBufferedSocket(bsocket);
bsocket=NULL;
}
@ -2732,7 +2731,7 @@ UBYTE NETrecvFile(NETQUEUE queue)
debug(LOG_FATAL, "PHYSFS_openRead(\"%s\") failed with error: %s\n", fileName, PHYSFS_getLastError());
debug(LOG_NET, "We are leaving 'nicely' after a fatal error");
NETbeginEncode(NET_PLAYER_LEAVING, NET_ALL_PLAYERS);
NETbeginEncode(NETbroadcastQueue(), NET_PLAYER_LEAVING);
{
BOOL host = NetPlay.isHost;
uint32_t id = selectedPlayer;

16
newnet.TODO Normal file
View File

@ -0,0 +1,16 @@
**************
* Everywhere *
**************
Remove bMultiPlayer and turnOffMultiMsg() hacks, cleaning up any duplicate or dead code on the way.
********************
* src/structure.c: *
********************
structPlaceDroid now sets ppsDroid to NULL. Check that that's ok with cbNewDroid. Since cbNewDroid is only called when the factory runs out of things to build, not every time a new droid is built, it smells like a giant hack, and maybe the droid can just be set to NULL.
Clean up structPlaceDroid. After which, the GAME_SECONDARY_ALL message type will be unused, and should be removed...
*****************
* src/keybind.c *
*****************
Fix kf_CloneSelected.

View File

@ -2381,8 +2381,7 @@ UDWORD calcDroidPoints(DROID *psDroid)
}
//Builds an instance of a Droid - the x/y passed in are in world coords.
DROID* buildDroid(DROID_TEMPLATE *pTemplate, UDWORD x, UDWORD y, UDWORD player,
BOOL onMission)
DROID *reallyBuildDroid(DROID_TEMPLATE *pTemplate, UDWORD x, UDWORD y, UDWORD player, BOOL onMission)
{
DROID *psDroid;
DROID_GROUP *psGrp;
@ -2577,15 +2576,6 @@ DROID* buildDroid(DROID_TEMPLATE *pTemplate, UDWORD x, UDWORD y, UDWORD player,
clustNewDroid(psDroid);
}
// ajl. droid will be created, so inform others
if(bMultiMessages)
{
if (SendDroid(pTemplate, x, y, (UBYTE)player, psDroid->id) == false)
{
return NULL;
}
}
/* transporter-specific stuff */
if (psDroid->droidType == DROID_TRANSPORTER)
{
@ -2610,6 +2600,23 @@ DROID* buildDroid(DROID_TEMPLATE *pTemplate, UDWORD x, UDWORD y, UDWORD player,
return psDroid;
}
DROID *buildDroid(DROID_TEMPLATE *pTemplate, UDWORD x, UDWORD y, UDWORD player, BOOL onMission, const INITIAL_DROID_ORDERS *initialOrders)
{
// ajl. droid will be created, so inform others
if (bMultiMessages)
{
if (!SendDroid(pTemplate, x, y, player, generateNewObjectId(), initialOrders))
{
debug(LOG_ERROR, "SendDroid failed?!");
}
return NULL;
}
else
{
return reallyBuildDroid(pTemplate, x, y, player, onMission);
}
}
//initialises the droid movement model
void initDroidMovement(DROID *psDroid)
{
@ -4298,7 +4305,7 @@ DROID * giftSingleDroid(DROID *psD, UDWORD to)
// make the old droid vanish
vanishDroid(psD);
// create a new droid
psNewDroid = buildDroid(&sTemplate, x, y, to, false);
psNewDroid = buildDroid(&sTemplate, x, y, to, false, NULL);
ASSERT(psNewDroid != NULL, "unable to build a unit");
if (psNewDroid)
{

View File

@ -94,9 +94,17 @@ extern BOOL loadDroidWeapons(const char *pWeaponData, UDWORD bufferSize);
/*initialise the template build and power points */
extern void initTemplatePoints(void);
typedef struct InitialDroidOrders
{
uint32_t secondaryOrder;
int32_t moveToX;
int32_t moveToY;
} INITIAL_DROID_ORDERS;
/*Builds an instance of a Structure - the x/y passed in are in world coords.*/
extern DROID* buildDroid(DROID_TEMPLATE *pTemplate, UDWORD x, UDWORD y,
UDWORD player, BOOL onMission);
/// Sends a GAME_DROID message if bMultiMessages is true, or actually creates it if false. Only uses initialOrders if sending a GAME_DROID message.
extern DROID* buildDroid(DROID_TEMPLATE *pTemplate, UDWORD x, UDWORD y, UDWORD player, BOOL onMission, const INITIAL_DROID_ORDERS *initialOrders);
/// Creates a droid locally, instead of sending a message, even if the bMultiMessages HACK is set to true.
DROID *reallyBuildDroid(DROID_TEMPLATE *pTemplate, UDWORD x, UDWORD y, UDWORD player, BOOL onMission);
/* Set the asBits in a DROID structure given it's template. */
extern void droidSetBits(DROID_TEMPLATE *pTemplate,DROID *psDroid);

View File

@ -5065,7 +5065,7 @@ BOOL loadSaveDroidInitV2(char *pFileData, UDWORD filesize,UDWORD quantity)
else
{
ASSERT(psTemplate != NULL, "Invalid template pointer");
psDroid = buildDroid(psTemplate, (pDroidInit->x & (~TILE_MASK)) + TILE_UNITS/2, (pDroidInit->y & (~TILE_MASK)) + TILE_UNITS/2, pDroidInit->player, false);
psDroid = reallyBuildDroid(psTemplate, (pDroidInit->x & ~TILE_MASK) + TILE_UNITS/2, (pDroidInit->y & ~TILE_MASK) + TILE_UNITS/2, pDroidInit->player, false);
if (psDroid)
{
@ -5228,8 +5228,7 @@ static DROID* buildDroidFromSaveDroidV11(SAVE_DROID_V11* psSaveDroid)
// ignore brains for now
psTemplate->asParts[COMP_BRAIN] = 0;
psDroid = buildDroid(psTemplate, psSaveDroid->x, psSaveDroid->y,
psSaveDroid->player, false);
psDroid = reallyBuildDroid(psTemplate, psSaveDroid->x, psSaveDroid->y, psSaveDroid->player, false);
//copy the droid's weapon stats
for (i=0; i < psDroid->numWeaps; i++)
@ -5336,18 +5335,15 @@ static DROID* buildDroidFromSaveDroidV19(SAVE_DROID_V18* psSaveDroid, UDWORD ver
if(psSaveDroid->x == INVALID_XY)
{
psDroid = buildDroid(psTemplate, psSaveDroid->x, psSaveDroid->y,
psSaveDroid->player, true);
psDroid = reallyBuildDroid(psTemplate, psSaveDroid->x, psSaveDroid->y, psSaveDroid->player, true);
}
else if(psSaveDroid->saveType == DROID_ON_TRANSPORT)
{
psDroid = buildDroid(psTemplate, 0, 0,
psSaveDroid->player, true);
psDroid = reallyBuildDroid(psTemplate, 0, 0, psSaveDroid->player, true);
}
else
{
psDroid = buildDroid(psTemplate, psSaveDroid->x, psSaveDroid->y,
psSaveDroid->player, false);
psDroid = reallyBuildDroid(psTemplate, psSaveDroid->x, psSaveDroid->y, psSaveDroid->player, false);
}
ASSERT_OR_RETURN(NULL, psDroid, "Failed to build unit");
@ -5716,18 +5712,15 @@ static DROID* buildDroidFromSaveDroid(SAVE_DROID* psSaveDroid, UDWORD version)
if(psSaveDroid->x == INVALID_XY)
{
psDroid = buildDroid(psTemplate, psSaveDroid->x, psSaveDroid->y,
psSaveDroid->player, true);
psDroid = reallyBuildDroid(psTemplate, psSaveDroid->x, psSaveDroid->y, psSaveDroid->player, true);
}
else if(psSaveDroid->saveType == DROID_ON_TRANSPORT)
{
psDroid = buildDroid(psTemplate, 0, 0,
psSaveDroid->player, true);
psDroid = reallyBuildDroid(psTemplate, 0, 0, psSaveDroid->player, true);
}
else
{
psDroid = buildDroid(psTemplate, psSaveDroid->x, psSaveDroid->y,
psSaveDroid->player, false);
psDroid = reallyBuildDroid(psTemplate, psSaveDroid->x, psSaveDroid->y, psSaveDroid->player, false);
}
ASSERT_OR_RETURN(NULL, psDroid, "Failed to build unit");

View File

@ -2158,20 +2158,26 @@ INT_RETVAL intRunWidgets(void)
else if (psPositionStats->ref >= REF_TEMPLATE_START &&
psPositionStats->ref < REF_TEMPLATE_START + REF_RANGE)
{
const char* msg;
psDroid = buildDroid((DROID_TEMPLATE *)psPositionStats,
world_coord(structX) + TILE_UNITS / 2, world_coord(structY) + TILE_UNITS / 2,
selectedPlayer, false);
selectedPlayer, false, NULL);
if (psDroid)
{
const char* msg;
addDroid(psDroid, apsDroidLists);
// Send a text message to all players, notifying them of
// the fact that we're cheating ourselves a new droid.
sasprintf((char**)&msg, _("Player %u is cheating (debug menu) him/herself a new droid: %s."), selectedPlayer, psDroid->aName);
sendTextMessage(msg, true);
Cheated = true;
}
else
{
// Send a text message to all players, notifying them of
// the fact that we're cheating ourselves a new droid.
sasprintf((char**)&msg, _("Player %u is cheating (debug menu) him/herself a new droid."), selectedPlayer);
}
sendTextMessage(msg, true);
Cheated = true;
}
editPosMode = IED_NOPOS;
}

View File

@ -299,7 +299,7 @@ void kf_CloneSelected( void )
DROID *psDroid, *psNewDroid;
DROID_TEMPLATE sTemplate;
const int limit = 10; // make 10 clones
int i, impact_side;
int i;
for (psDroid = apsDroidLists[selectedPlayer]; psDroid; psDroid=psDroid->psNext)
{
@ -312,7 +312,8 @@ void kf_CloneSelected( void )
sstrcpy(sTemplate.aName, psDroid->aName);
// create a new droid
psNewDroid = buildDroid(&sTemplate, psDroid->pos.x, psDroid->pos.y, psDroid->player, false);
psNewDroid = buildDroid(&sTemplate, psDroid->pos.x, psDroid->pos.y, psDroid->player, false, NULL);
/* // TODO psNewDroid is null, since we just sent a message, but haven't actually created the droid locally yet.
ASSERT_OR_RETURN(, psNewDroid != NULL, "Unable to build a unit");
addDroid(psNewDroid, apsDroidLists);
psNewDroid->body = psDroid->body;
@ -328,6 +329,7 @@ void kf_CloneSelected( void )
updateDroidOrientation(psNewDroid);
}
psNewDroid->selected = true;
*/
}
}
}

View File

@ -2692,7 +2692,7 @@ DROID * buildMissionDroid(DROID_TEMPLATE *psTempl, UDWORD x, UDWORD y,
{
DROID *psNewDroid;
psNewDroid = buildDroid(psTempl, world_coord(x), world_coord(y), player, true);
psNewDroid = buildDroid(psTempl, world_coord(x), world_coord(y), player, true, NULL);
if (!psNewDroid)
{
return NULL;

View File

@ -517,7 +517,7 @@ BOOL recvDroidMove(NETQUEUE queue)
// ////////////////////////////////////////////////////////////////////////////
// Send a new Droid to the other players
BOOL SendDroid(const DROID_TEMPLATE* pTemplate, uint32_t x, uint32_t y, uint8_t player, uint32_t id)
BOOL SendDroid(const DROID_TEMPLATE* pTemplate, uint32_t x, uint32_t y, uint8_t player, uint32_t id, const INITIAL_DROID_ORDERS *initialOrdersP)
{
if (!bMultiMessages)
return true;
@ -543,14 +543,20 @@ BOOL SendDroid(const DROID_TEMPLATE* pTemplate, uint32_t x, uint32_t y, uint8_t
{
Vector3uw pos = { x, y, 0 };
uint32_t templateID = pTemplate->multiPlayerID;
uint32_t power = getPower(player);
BOOL haveInitialOrders = initialOrdersP != NULL;
NETuint8_t(&player);
NETuint32_t(&id);
NETVector3uw(&pos);
NETuint32_t(&templateID);
NETuint32_t(&power); // update player's power as well.
NETbool(&powerCalculated);
NETbool(&haveInitialOrders);
if (haveInitialOrders)
{
INITIAL_DROID_ORDERS initialOrders = *initialOrdersP;
NETuint32_t(&initialOrders.secondaryOrder);
NETint32_t(&initialOrders.moveToX);
NETint32_t(&initialOrders.moveToY);
}
}
debug(LOG_LIFE, "===> sending Droid from %u id of %u ",player,id);
return NETend();
@ -565,9 +571,9 @@ BOOL recvDroid(NETQUEUE queue)
uint8_t player;
uint32_t id;
Vector3uw pos;
BOOL powerCalculated;
uint32_t templateID;
uint32_t power;
BOOL haveInitialOrders;
INITIAL_DROID_ORDERS initialOrders;
NETbeginDecode(queue, GAME_DROID);
{
@ -575,8 +581,13 @@ BOOL recvDroid(NETQUEUE queue)
NETuint32_t(&id);
NETVector3uw(&pos);
NETuint32_t(&templateID);
NETuint32_t(&power);
NETbool(&powerCalculated);
NETbool(&haveInitialOrders);
if (haveInitialOrders)
{
NETuint32_t(&initialOrders.secondaryOrder);
NETint32_t(&initialOrders.moveToX);
NETint32_t(&initialOrders.moveToY);
}
pT = IdToTemplate(templateID, player);
}
@ -600,21 +611,20 @@ BOOL recvDroid(NETQUEUE queue)
return false;
}
// forget about calculating the power, we *know* they built it, so we set
// their power accordingly on the local machine.
setPower((uint32_t) player, power);
debug(LOG_SYNC, "Syncing players %u power to %u", player, power);
// Create that droid on this machine.
turnOffMultiMsg(true);
psDroid = buildDroid(pT, pos.x, pos.y, player, false);
turnOffMultiMsg(false);
psDroid = reallyBuildDroid(pT, pos.x, pos.y, player, false);
// If we were able to build the droid set it up
if (psDroid)
{
psDroid->id = id;
addDroid(psDroid, apsDroidLists);
if (haveInitialOrders)
{
psDroid->secondaryOrder = initialOrders.secondaryOrder;
orderDroidLoc(psDroid, DORDER_MOVE, initialOrders.moveToX, initialOrders.moveToY);
}
}
else
{

View File

@ -586,7 +586,7 @@ BOOL recvMessage(void)
switch (type)
{
// TODO Remove all these cases.
case GAME_DROID:
//case GAME_DROID: //24 down, 18 to go.
//case GAME_DROIDINFO: // 2 down, 41 to go.
case GAME_DROIDDEST:
//case GAME_DROIDMOVE: // 1 down, 42 to go.

View File

@ -26,6 +26,7 @@
#include "group.h"
#include "featuredef.h"
#include "droid.h" // For INITIAL_DROID_ORDERS.
#ifdef __cplusplus
extern "C"
@ -167,7 +168,7 @@ extern BOOL sendLasSat (UBYTE player, STRUCTURE *psStruct, BASE_OBJECT *psObj)
// droids . multibot
extern BOOL SendDroid (const DROID_TEMPLATE* pTemplate, uint32_t x, uint32_t y, uint8_t player, uint32_t id);
extern BOOL SendDroid (const DROID_TEMPLATE* pTemplate, uint32_t x, uint32_t y, uint8_t player, uint32_t id, const INITIAL_DROID_ORDERS *initialOrders);
extern BOOL SendDestroyDroid (const DROID* psDroid);
extern BOOL SendDemolishFinished(STRUCTURE *psS,DROID *psD);
extern BOOL SendDroidInfo (const DROID* psDroid, DROID_ORDER order, uint32_t x, uint32_t y, const BASE_OBJECT* psObj);

View File

@ -1012,7 +1012,7 @@ BOOL scrAddDroid(void)
} else
#endif
{
psDroid = buildDroid(psTemplate, x, y, player, false);
psDroid = buildDroid(psTemplate, x, y, player, false, NULL);
if (psDroid)
{
addDroid(psDroid, apsDroidLists);
@ -1025,7 +1025,7 @@ BOOL scrAddDroid(void)
}
else
{
debug( LOG_LIFE, "failed to create droid for AI player %d", player );
debug(LOG_LIFE, "send droid create message to game queue for AI player %d", player );
}
}

View File

@ -2588,9 +2588,9 @@ static BOOL structPlaceDroid(STRUCTURE *psStructure, DROID_TEMPLATE *psTempl,
if (placed)
{
INITIAL_DROID_ORDERS initialOrders = {psStructure->pFunctionality->factory.secondaryOrder, psStructure->pFunctionality->factory.psAssemblyPoint->coords.x, psStructure->pFunctionality->factory.psAssemblyPoint->coords.y};
//create a droid near to the structure
psNewDroid = buildDroid(psTempl, world_coord(x), world_coord(y),
psStructure->player, false);
psNewDroid = buildDroid(psTempl, world_coord(x), world_coord(y), psStructure->player, false, &initialOrders);
if (!psNewDroid)
{
*ppsDroid = NULL;