예제 #1
0
// ////////////////////////////////////////////////////////////////////////////
// Send a new Droid to the other players
bool SendDroid(DROID_TEMPLATE *pTemplate, uint32_t x, uint32_t y, uint8_t player, uint32_t id, const INITIAL_DROID_ORDERS *initialOrdersP)
{
	if (!bMultiMessages)
	{
		return true;
	}

	ASSERT_OR_RETURN(false, x != 0 && y != 0, "SendDroid: Invalid droid coordinates");
	ASSERT_OR_RETURN(false, player < MAX_PLAYERS, "invalid player %u", player);

	// Dont send other droids during campaign setup
	if (ingame.localJoiningInProgress)
	{
		return true;
	}

	// Only send the droid if we are responsible
	if (!myResponsibility(player))
	{
		// Don't build if we are not responsible
		return false;
	}

	debug(LOG_SYNC, "Droid sent with id of %u", id);
	NETbeginEncode(NETgameQueue(selectedPlayer), GAME_DEBUG_ADD_DROID);
	{
		Position pos(x, y, 0);
		bool haveInitialOrders = initialOrdersP != NULL;
		int32_t droidType = pTemplate->droidType;

		NETuint8_t(&player);
		NETuint32_t(&id);
		NETPosition(&pos);
		NETqstring(pTemplate->name);
		NETint32_t(&droidType);
		NETuint8_t(&pTemplate->asParts[COMP_BODY]);
		NETuint8_t(&pTemplate->asParts[COMP_BRAIN]);
		NETuint8_t(&pTemplate->asParts[COMP_PROPULSION]);
		NETuint8_t(&pTemplate->asParts[COMP_REPAIRUNIT]);
		NETuint8_t(&pTemplate->asParts[COMP_ECM]);
		NETuint8_t(&pTemplate->asParts[COMP_SENSOR]);
		NETuint8_t(&pTemplate->asParts[COMP_CONSTRUCT]);
		NETint8_t(&pTemplate->numWeaps);
		for (int i = 0; i < pTemplate->numWeaps; i++)
		{
			NETuint8_t(&pTemplate->asWeaps[i]);
		}
		NETbool(&haveInitialOrders);
		if (haveInitialOrders)
		{
			INITIAL_DROID_ORDERS initialOrders = *initialOrdersP;
			NETuint32_t(&initialOrders.secondaryOrder);
			NETint32_t(&initialOrders.moveToX);
			NETint32_t(&initialOrders.moveToY);
			NETuint32_t(&initialOrders.factoryId);  // For making scripts happy.
		}
	}
	debug(LOG_LIFE, "===> sending Droid from %u id of %u ", player, id);
	return NETend();
}
예제 #2
0
// ////////////////////////////////////////////////////////////////////////////
// INFORM others that a building has been completed.
BOOL SendBuildFinished(STRUCTURE *psStruct)
{
	uint8_t player = psStruct->player;
	ASSERT( player < MAX_PLAYERS, "invalid player %u", player);

	NETbeginEncode(NETgameQueue(selectedPlayer), GAME_BUILDFINISHED);
		NETuint32_t(&psStruct->id);		// ID of building

		// Along with enough info to build it (if needed)
		NETuint32_t(&psStruct->pStructureType->ref);
		NETPosition(&psStruct->pos);
		NETuint8_t(&player);
	return NETend();
}
// ////////////////////////////////////////////////////////////////////////////
// INFORM others that a building has been completed.
BOOL SendBuildFinished(STRUCTURE *psStruct)
{
    uint32_t power = getPower( (uint32_t) psStruct->player);
    uint8_t player = psStruct->player;
    ASSERT( player < MAX_PLAYERS, "invalid player %u", player);

    NETbeginEncode(NET_BUILDFINISHED, NET_ALL_PLAYERS);
    NETuint32_t(&power);			// send how much power we got.
    NETuint32_t(&psStruct->id);		// ID of building

    // Along with enough info to build it (if needed)
    NETuint32_t(&psStruct->pStructureType->ref);
    NETPosition(&psStruct->pos);
    NETuint8_t(&player);
    return NETend();
}
예제 #4
0
// ////////////////////////////////////////////////////////////////////////////
// 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, const INITIAL_DROID_ORDERS *initialOrdersP)
{
	if (!bMultiMessages)
		return true;

	ASSERT(x != 0 && y != 0, "SendDroid: Invalid droid coordinates");
	ASSERT( player < MAX_PLAYERS, "invalid player %u", player);

	// Dont send other droids during campaign setup
	if (ingame.localJoiningInProgress)
	{
		return true;
	}

	// Only send the droid if we are responsible
	if (!myResponsibility(player))
	{
		// Don't build if we are not responsible
		return false;
	}

	debug(LOG_SYNC, "Droid sent with id of %u", id);
	NETbeginEncode(NETgameQueue(selectedPlayer), GAME_DROID);
	{
		Position pos = { x, y, 0 };
		uint32_t templateID = pTemplate->multiPlayerID;
		BOOL haveInitialOrders = initialOrdersP != NULL;

		NETuint8_t(&player);
		NETuint32_t(&id);
		NETPosition(&pos);
		NETuint32_t(&templateID);
		NETbool(&haveInitialOrders);
		if (haveInitialOrders)
		{
			INITIAL_DROID_ORDERS initialOrders = *initialOrdersP;
			NETuint32_t(&initialOrders.secondaryOrder);
			NETint32_t(&initialOrders.moveToX);
			NETint32_t(&initialOrders.moveToY);
			NETuint32_t(&initialOrders.factoryId);  // For making scripts happy.
		}
	}
	debug(LOG_LIFE, "===> sending Droid from %u id of %u ",player,id);
	return NETend();
}
예제 #5
0
/** Broadcast that droid is being unloaded from a transporter
 *
 *  \sa sendDroidEmbark(),recvDroidEmbark(),recvDroidDisEmbark()
 */
BOOL sendDroidDisEmbark(const DROID* psDroid, const DROID* psTransporter)
{
	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);

		NETuint8_t(&player);
		NETuint32_t(&droidID);
		NETuint32_t(&transporterID);
		NETPosition(&pos);
	}
	return NETend();
}
예제 #6
0
// ////////////////////////////////////////////////////////////////////////////
// receive droid creation information from other players
BOOL recvDroid(NETQUEUE queue)
{
	DROID_TEMPLATE* pT;
	DROID* psDroid;
	uint8_t player;
	uint32_t id;
	Position pos;
	uint32_t templateID;
	BOOL haveInitialOrders;
	INITIAL_DROID_ORDERS initialOrders;

	NETbeginDecode(queue, GAME_DROID);
	{
		NETuint8_t(&player);
		NETuint32_t(&id);
		NETPosition(&pos);
		NETuint32_t(&templateID);
		NETbool(&haveInitialOrders);
		if (haveInitialOrders)
		{
			NETuint32_t(&initialOrders.secondaryOrder);
			NETint32_t(&initialOrders.moveToX);
			NETint32_t(&initialOrders.moveToY);
			NETuint32_t(&initialOrders.factoryId);  // For making scripts happy.
		}

		pT = IdToTemplate(templateID, player);
	}
	NETend();

	ASSERT( player < MAX_PLAYERS, "invalid player %u", player);

	debug(LOG_LIFE, "<=== getting Droid from %u id of %u ",player,id);
	if ((pos.x == 0 && pos.y == 0) || pos.x > world_coord(mapWidth) || pos.y > world_coord(mapHeight))
	{
		debug(LOG_ERROR, "Received bad droid position (%d, %d) from %d about p%d (%s)", (int)pos.x, (int)pos.y,
				queue.index, player, isHumanPlayer(player) ? "Human" : "AI");
		return false;
	}

	// If we can not find the template ask for the entire droid instead
	if (!pT)
	{
		debug(LOG_ERROR, "Packet from %d refers to non-existent template %u, [%s : p%d]",
				queue.index, templateID, isHumanPlayer(player) ? "Human" : "AI", player);
		return false;
	}

	// Create that droid on this machine.
	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, ModeImmediate);
			cbNewDroid(IdToStruct(initialOrders.factoryId, ANYPLAYER), psDroid);
		}
	}
	else
	{
		debug(LOG_ERROR, "Packet from %d cannot create droid for p%d (%s)!", queue.index,
			player, isHumanPlayer(player) ? "Human" : "AI");
#ifdef DEBUG
		CONPRINTF(ConsoleString, (ConsoleString, "MULTIPLAYER: Couldn't build a remote droid, relying on checking to resync"));
#endif
		return false;
	}

	return true;
}
예제 #7
0
/** Receive info about a droid that is being unloaded from a transporter
 *
 *  \sa sendDroidEmbark(),recvDroidEmbark(),sendDroidDisEmbark()
 */
BOOL recvDroidDisEmbark(NETQUEUE queue)
{
	DROID *psFoundDroid = NULL, *psTransporterDroid = NULL;
	DROID *psCheckDroid = NULL;

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

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

		NETend();

		// 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;
		}

		// 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
		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);
	}
	return true;
}
예제 #8
0
// ////////////////////////////////////////////////////////////////////////////
BOOL recvBuildFinished(NETQUEUE queue)
{
	uint32_t	structId;
	STRUCTURE	*psStruct;
	Position        pos;
	uint32_t	type,typeindex;
	uint8_t		player;

	NETbeginDecode(queue, GAME_BUILDFINISHED);
		NETuint32_t(&structId);	// get the struct id.
		NETuint32_t(&type); 	// Kind of building.
		NETPosition(&pos);      // pos
		NETuint8_t(&player);
	NETend();

	ASSERT( player < MAX_PLAYERS, "invalid player %u", player);

	psStruct = IdToStruct(structId,ANYPLAYER);

	if (psStruct)
	{												// make it complete.
		psStruct->currentBuildPts = psStruct->pStructureType->buildPoints+1;

		if (psStruct->status != SS_BUILT)
		{
			debug(LOG_SYNC, "Synch error, structure %u was not complete, and should have been.", structId);
			psStruct->status = SS_BUILT;
			buildingComplete(psStruct);
		}
		debug(LOG_SYNC, "Created normal building %u for player %u", psStruct->id, player);
		return true;
	}

	// The building wasn't started, so we'll have to just plonk it down in the map.

	// Find the structures stats
	for (typeindex=0;						// Find structure target
		(typeindex<numStructureStats ) && (asStructureStats[typeindex].ref != type);
		typeindex++);

	// Check for similar buildings, to avoid overlaps
	if (TileHasStructure(mapTile(map_coord(pos.x), map_coord(pos.y))))
	{
		// Get the current structure
		psStruct = getTileStructure(map_coord(pos.x), map_coord(pos.y));
		if (asStructureStats[typeindex].type == psStruct->pStructureType->type)
		{
			// Correct type, correct location, just rename the id's to sync it.. (urgh)
			psStruct->id = structId;
			psStruct->status = SS_BUILT;
			buildingComplete(psStruct);
			debug(LOG_SYNC, "Created modified building %u for player %u", psStruct->id, player);
#if defined (DEBUG)
			NETlogEntry("structure id modified", SYNC_FLAG, player);
#endif
			return true;
		}
	}
	// Build the structure
	psStruct = buildStructure(&(asStructureStats[typeindex]), pos.x, pos.y, player, true);

	if (psStruct)
	{
		psStruct->id		= structId;
		psStruct->status	= SS_BUILT;
		buildingComplete(psStruct);
		debug(LOG_SYNC, "Huge synch error, forced to create building %u for player %u", psStruct->id, player);
#if defined (DEBUG)
		NETlogEntry("had to plonk down a building", SYNC_FLAG, player);
#endif
	}
	else
	{
		debug(LOG_SYNC, "Gigantic synch error, unable to create building for player %u", player);
		NETlogEntry("had to plonk down a building, BUT FAILED!", SYNC_FLAG, player);
	}

	return false;
}
예제 #9
0
// ////////////////////////////////////////////////////////////////////////////
// receive droid creation information from other players
bool recvDroid(NETQUEUE queue)
{
	DROID_TEMPLATE t, *pT = &t;
	DROID *psDroid;
	uint8_t player;
	uint32_t id;
	Position pos;
	bool haveInitialOrders;
	INITIAL_DROID_ORDERS initialOrders;

	NETbeginDecode(queue, GAME_DEBUG_ADD_DROID);
	{
		int32_t droidType;

		NETuint8_t(&player);
		NETuint32_t(&id);
		NETPosition(&pos);
		NETqstring(pT->name);
		pT->id = pT->name;
		NETint32_t(&droidType);
		NETuint8_t(&pT->asParts[COMP_BODY]);
		NETuint8_t(&pT->asParts[COMP_BRAIN]);
		NETuint8_t(&pT->asParts[COMP_PROPULSION]);
		NETuint8_t(&pT->asParts[COMP_REPAIRUNIT]);
		NETuint8_t(&pT->asParts[COMP_ECM]);
		NETuint8_t(&pT->asParts[COMP_SENSOR]);
		NETuint8_t(&pT->asParts[COMP_CONSTRUCT]);
		NETint8_t(&pT->numWeaps);
		for (int i = 0; i < pT->numWeaps; i++)
		{
			NETuint8_t(&pT->asWeaps[i]);
		}
		NETbool(&haveInitialOrders);
		if (haveInitialOrders)
		{
			NETuint32_t(&initialOrders.secondaryOrder);
			NETint32_t(&initialOrders.moveToX);
			NETint32_t(&initialOrders.moveToY);
			NETuint32_t(&initialOrders.factoryId);  // For making scripts happy.
		}
		pT->droidType = (DROID_TYPE)droidType;
	}
	NETend();

	if (!getDebugMappingStatus() && bMultiPlayer)
	{
		debug(LOG_WARNING, "Failed to add droid for player %u.", NetPlay.players[queue.index].position);
		return false;
	}

	ASSERT_OR_RETURN(false, player < MAX_PLAYERS, "invalid player %u", player);

	debug(LOG_LIFE, "<=== getting Droid from %u id of %u ", player, id);
	if ((pos.x == 0 && pos.y == 0) || pos.x > world_coord(mapWidth) || pos.y > world_coord(mapHeight))
	{
		debug(LOG_ERROR, "Received bad droid position (%d, %d) from %d about p%d (%s)", (int)pos.x, (int)pos.y,
		      queue.index, player, isHumanPlayer(player) ? "Human" : "AI");
		return false;
	}

	// Create that droid on this machine.
	psDroid = reallyBuildDroid(pT, pos, 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;
			psDroid->secondaryOrderPending = psDroid->secondaryOrder;
			orderDroidLoc(psDroid, DORDER_MOVE, initialOrders.moveToX, initialOrders.moveToY, ModeImmediate);
			cbNewDroid(IdToStruct(initialOrders.factoryId, ANYPLAYER), psDroid);
		}

		syncDebugDroid(psDroid, '+');
	}
	else
	{
		debug(LOG_ERROR, "Packet from %d cannot create droid for p%d (%s)!", queue.index,
		      player, isHumanPlayer(player) ? "Human" : "AI");
#ifdef DEBUG
		CONPRINTF(ConsoleString, (ConsoleString, "MULTIPLAYER: Couldn't build a remote droid, relying on checking to resync"));
#endif
		return false;
	}

	return true;
}