Esempio n. 1
0
// ////////////////////////////////////////////////////////////////////////////
// receive droid information form other players.
BOOL recvDroidInfo(NETQUEUE queue)
{
	NETbeginDecode(queue, GAME_DROIDINFO);
	{
		QueuedDroidInfo info;
		memset(&info, 0x00, sizeof(info));
		NETQueuedDroidInfo(&info);

		STRUCTURE_STATS *psStats = NULL;
		if (info.order == DORDER_BUILD || info.order == DORDER_LINEBUILD)
		{
			// Find structure target
			for (unsigned typeIndex = 0; typeIndex < numStructureStats; typeIndex++)
			{
				if (asStructureStats[typeIndex].ref == info.structRef)
				{
					psStats = asStructureStats + typeIndex;
					break;
				}
			}
		}

		if (info.subType)
		{
			syncDebug("Order=%s,%d(%d)", getDroidOrderName(info.order), info.destId, info.destType);
		}
		else
		{
			syncDebug("Order=%s,(%d,%d)", getDroidOrderName(info.order), info.x, info.y);
		}

		DROID_ORDER_DATA sOrder;
		memset(&sOrder, 0x00, sizeof(sOrder));
		sOrder.order = info.order;
		sOrder.x = info.x;
		sOrder.y = info.y;
		sOrder.x2 = info.x2;
		sOrder.y2 = info.y2;
		sOrder.direction = info.direction;
		sOrder.psObj = processDroidTarget(info.destType, info.destId);
		sOrder.psStats = (BASE_STATS *)psStats;

		uint32_t num = 0;
		NETuint32_t(&num);

		for (unsigned n = 0; n < num; ++n)
		{
			// Get the next droid ID which is being given this order.
			uint32_t deltaDroidId = 0;
			NETuint32_t(&deltaDroidId);
			info.droidId += deltaDroidId;

			DROID *psDroid = NULL;
			if (!IdToDroid(info.droidId, ANYPLAYER, &psDroid))
			{
				debug(LOG_NEVER, "Packet from %d refers to non-existent droid %u, [%s : p%d]",
				      queue.index, info.droidId, isHumanPlayer(info.player) ? "Human" : "AI", info.player);
				syncDebug("Droid %d missing", info.droidId);
				continue;  // Can't find the droid, so skip this droid.
			}

			CHECK_DROID(psDroid);

			syncDebugDroid(psDroid, '<');

			psDroid->waitingForOwnReceiveDroidInfoMessage = false;

			/*
			* If the current order not is a command order and we are not a
			* commander yet are in the commander group remove us from it.
			*/
			if (hasCommander(psDroid))
			{
				grpLeave(psDroid->psGroup, psDroid);
			}

			if (sOrder.psObj != TargetMissing)  // Only do order if the target didn't die.
			{
				orderDroidBase(psDroid, &sOrder);
			}

			syncDebugDroid(psDroid, '>');

			CHECK_DROID(psDroid);
		}
	}
	NETend();

	return true;
}
Esempio n. 2
0
// ////////////////////////////////////////////////////////////////////////////
// receive droid information form other players.
bool recvDroidInfo(NETQUEUE queue)
{
	NETbeginDecode(queue, GAME_DROIDINFO);
	{
		QueuedDroidInfo info;
		memset(&info, 0x00, sizeof(info));
		NETQueuedDroidInfo(&info);

		STRUCTURE_STATS *psStats = NULL;
		if (info.subType == LocOrder && (info.order == DORDER_BUILD || info.order == DORDER_LINEBUILD))
		{
			// Find structure target
			for (unsigned typeIndex = 0; typeIndex < numStructureStats; typeIndex++)
			{
				if (asStructureStats[typeIndex].ref == info.structRef)
				{
					psStats = asStructureStats + typeIndex;
					break;
				}
			}
		}

		switch (info.subType)
		{
			case ObjOrder:       syncDebug("Order=%s,%d(%d)", getDroidOrderName(info.order), info.destId, info.destType); break;
			case LocOrder:       syncDebug("Order=%s,(%d,%d)", getDroidOrderName(info.order), info.pos.x, info.pos.y); break;
			case SecondaryOrder: syncDebug("SecondaryOrder=%d,%08X", (int)info.secOrder, (int)info.secState); break;
		}

		DROID_ORDER_DATA sOrder = infoToOrderData(info, psStats);

		uint32_t num = 0;
		NETuint32_t(&num);

		for (unsigned n = 0; n < num; ++n)
		{
			// Get the next droid ID which is being given this order.
			uint32_t deltaDroidId = 0;
			NETuint32_t(&deltaDroidId);
			info.droidId += deltaDroidId;

			DROID *psDroid = IdToDroid(info.droidId, info.player);
			if (!psDroid)
			{
				debug(LOG_NEVER, "Packet from %d refers to non-existent droid %u, [%s : p%d]",
				      queue.index, info.droidId, isHumanPlayer(info.player) ? "Human" : "AI", info.player);
				syncDebug("Droid %d missing", info.droidId);
				continue;  // Can't find the droid, so skip this droid.
			}

			CHECK_DROID(psDroid);

			syncDebugDroid(psDroid, '<');

			switch (info.subType)
			{
				case ObjOrder:
				case LocOrder:
					/*
					* If the current order not is a command order and we are not a
					* commander yet are in the commander group remove us from it.
					*/
					if (hasCommander(psDroid))
					{
						psDroid->psGroup->remove(psDroid);
					}

					if (sOrder.psObj != TargetMissing)  // Only do order if the target didn't die.
					{
						if (!info.add)
						{
							orderDroidListEraseRange(psDroid, 0, psDroid->listSize + 1);  // Clear all non-pending orders, plus the first pending order (which is probably the order we just received).
							orderDroidBase(psDroid, &sOrder);  // Execute the order immediately (even if in the middle of another order.
						}
						else
						{
							orderDroidAdd(psDroid, &sOrder);   // Add the order to the (non-pending) list. Will probably overwrite the corresponding pending order, assuming all pending orders were written to the list.
						}
					}
					break;
				case SecondaryOrder:
					// Set the droids secondary order
					turnOffMultiMsg(true);
					secondarySetState(psDroid, info.secOrder, info.secState);
					turnOffMultiMsg(false);
					break;
			}

			syncDebugDroid(psDroid, '>');

			CHECK_DROID(psDroid);
		}
	}
	NETend();

	return true;
}