Example #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();
}
//
// At this time, we do NOT support messages for beacons
//
bool sendBeacon(int32_t locX, int32_t locY, int32_t forPlayer, int32_t sender, const char* pStr)
{
	int sendPlayer;
	//debug(LOG_WZ, "sendBeacon: '%s'",pStr);

	//find machine that is hosting this human or AI
	sendPlayer = whosResponsible(forPlayer);

	if(sendPlayer >= MAX_PLAYERS)
	{
		debug(LOG_ERROR, "sendAIMessage() - whosResponsible() failed.");
		return false;
	}

	// I assume this is correct, looks like it sends it to ONLY that person, and the routine
	// kf_AddHelpBlip() iterates for each player it needs.
	NETbeginEncode(NETnetQueue(sendPlayer), NET_BEACONMSG);    // send to the player who is hosting 'to' player (might be himself if human and not AI)
		NETint32_t(&sender);                                // save the actual sender

		// save the actual player that is to get this msg on the source machine (source can host many AIs)
		NETint32_t(&forPlayer);                             // save the actual receiver (might not be the same as the one we are actually sending to, in case of AIs)
		NETint32_t(&locX);                                  // save location
		NETint32_t(&locY);

		// const_cast: need to cast away constness because of the const-incorrectness of NETstring (const-incorrect when sending/encoding a packet)
		NETstring((char*)pStr, MAX_CONSOLE_STRING_LENGTH);  // copy message in.
	NETend();

	return true;
}
Example #3
0
BOOL recvAlliance(BOOL allowAudio)
{
	uint8_t to, from, state;
	int32_t value;

	NETbeginDecode(NET_ALLIANCE);
		NETuint8_t(&from);
		NETuint8_t(&to);
		NETuint8_t(&state);
		NETint32_t(&value);
	NETend();

	switch (state)
	{
		case ALLIANCE_NULL:
			break;
		case ALLIANCE_REQUESTED:
			requestAlliance(from, to, false, allowAudio);
			break;
		case ALLIANCE_FORMED:
			formAlliance(from, to, false, allowAudio, true);
			break;
		case ALLIANCE_BROKEN:
			breakAlliance(from, to, false, allowAudio);
			break;
		default:
			debug(LOG_ERROR, "Unknown alliance state recvd.");
			return false;
			break;
	}

	return true;
}
Example #4
0
static void NETcoder(PACKETDIR dir)
{
	static const char original[] = "THIS IS A TEST STRING";
	char str[sizeof(original)];
	BOOL b = true;
	uint32_t u32 = 32;
	uint16_t u16 = 16;
	uint8_t u8 = 8;
	int32_t i32 = -32;
	int16_t i16 = -16;
	int8_t i8 = -8;
	test_enum te = test_b;

	sstrcpy(str, original);

	if (dir == PACKET_ENCODE)
		NETbeginEncode(0, 0);
	else
		NETbeginDecode(0);
	NETbool(&b);			assert(b == true);
	NETuint32_t(&u32);  assert(u32 == 32);
	NETuint16_t(&u16);  assert(u16 == 16);
	NETuint8_t(&u8);    assert(u8 == 8);
	NETint32_t(&i32);   assert(i32 == -32);
	NETint16_t(&i16);   assert(i16 == -16);
	NETint8_t(&i8);     assert(i8 == -8);
	NETstring(str, sizeof(str)); assert(strncmp(str, original, sizeof(str) - 1) == 0);
	NETenum(&te);       assert(te == test_b);
}
Example #5
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();
}
Example #6
0
void sendAlliance(uint8_t from, uint8_t to, uint8_t state, int32_t value)
{
	NETbeginEncode(NETgameQueue(selectedPlayer), GAME_ALLIANCE);
	NETuint8_t(&from);
	NETuint8_t(&to);
	NETuint8_t(&state);
	NETint32_t(&value);
	NETend();
}
Example #7
0
void sendAlliance(uint8_t from, uint8_t to, uint8_t state, int32_t value)
{
	NETbeginEncode(NET_ALLIANCE, NET_ALL_PLAYERS);
		NETuint8_t(&from);
		NETuint8_t(&to);
		NETuint8_t(&state);
		NETint32_t(&value);
	NETend();
}
static bool recvBeacon(NETQUEUE queue)
{
	int32_t sender, receiver,locX, locY;
	char    msg[MAX_CONSOLE_STRING_LENGTH];

	NETbeginDecode(queue, NET_BEACONMSG);
	    NETint32_t(&sender);            // the actual sender
	    NETint32_t(&receiver);          // the actual receiver (might not be the same as the one we are actually sending to, in case of AIs)
	    NETint32_t(&locX);
	    NETint32_t(&locY);
	    NETstring(msg, sizeof(msg));    // Receive the actual message
	NETend();

	debug(LOG_WZ, "Received beacon for player: %d, from: %d",receiver, sender);

	sstrcat(msg, NetPlay.players[sender].name);    // name
	sstrcpy(beaconReceiveMsg[sender], msg);

	return addBeaconBlip(locX, locY, receiver, sender, beaconReceiveMsg[sender]);
}
// ////////////////////////////////////////////////////////////////////////////
// INFORM others that a building has been started, and base plate should be put down.
BOOL sendBuildStarted(STRUCTURE *psStruct, DROID *psDroid)
{
    NETbeginEncode(NET_BUILD, NET_ALL_PLAYERS);

    // Who is building it
    NETuint8_t(&psDroid->player);

    // What they are building
    NETuint32_t(&psDroid->psTarStats->ref);

    // Where it is being built
    NETuint16_t(&psDroid->orderX);
    NETuint16_t(&psDroid->orderY);

    // The droid building it
    NETuint32_t(&psDroid->id);

    // The ID assigned to the structure being built
    NETuint32_t(&psStruct->id);

    // The droids order
    NETint32_t(&psDroid->order);

    if (psDroid->psTarget
            && psDroid->psTarget->type == OBJ_STRUCTURE)
    {
        // The ID of the droids target (== psStruct->id ?)
        NETuint32_t(&psDroid->psTarget->id);
    }
    else
    {
        NETnull();
    }

    // Z coord
    NETint32_t(&psStruct->pos.z);

    return NETend();
}
Example #10
0
bool recvAlliance(NETQUEUE queue, bool allowAudio)
{
	uint8_t to, from, state;
	int32_t value;

	NETbeginDecode(queue, GAME_ALLIANCE);
		NETuint8_t(&from);
		NETuint8_t(&to);
		NETuint8_t(&state);
		NETint32_t(&value);
	NETend();

	switch (state)
	{
		case ALLIANCE_NULL:
			break;
		case ALLIANCE_REQUESTED:
			turnOffMultiMsg(true);
			requestAlliance(from, to, false, allowAudio);
			turnOffMultiMsg(false);
			break;
		case ALLIANCE_FORMED:
			turnOffMultiMsg(true);
			formAlliance(from, to, false, allowAudio, true);
			turnOffMultiMsg(false);
			break;
		case ALLIANCE_BROKEN:
			turnOffMultiMsg(true);
			breakAlliance(from, to, false, allowAudio);
			turnOffMultiMsg(false);
			break;
		default:
			debug(LOG_ERROR, "Unknown alliance state recvd.");
			return false;
			break;
	}

	return true;
}
Example #11
0
BOOL NETfloat(float *fp)
{
	/*
	 * NB: Not portable.
	 * This routine only works on machines with IEEE754 floating point numbers.
	 */

	#if !defined(__STDC_IEC_559__) \
	 && !defined(__m68k__) && !defined(__sparc__) && !defined(__i386__) \
	 && !defined(__mips__) && !defined(__ns32k__) && !defined(__alpha__) \
	 && !defined(__arm__) && !defined(__ppc__) && !defined(__ia64__) \
	 && !defined(__arm26__) && !defined(__sparc64__) && !defined(__amd64__) \
	 && !defined(WZ_CC_MSVC) // Assume that all platforms supported by
	                         // MSVC provide IEEE754 floating point numbers
	# error "this platform hasn't been confirmed to support IEEE754 floating point numbers"
	#endif

	// IEEE754 floating point numbers can be treated the same as 32-bit integers
	// with regards to endian conversion
	STATIC_ASSERT(sizeof(float) == sizeof(int32_t));

	return NETint32_t((int32_t *) fp);
}
Example #12
0
static void NETtemplate(DROID_TEMPLATE *pTempl)
{
	NETstring(pTempl->aName, sizeof(pTempl->aName));

	for (unsigned i = 0; i < ARRAY_SIZE(pTempl->asParts); ++i)
	{
		// signed, but sent as a bunch of bits...
		NETint32_t(&pTempl->asParts[i]);
	}

	NETuint32_t(&pTempl->buildPoints);
	NETuint32_t(&pTempl->powerPoints);
	NETuint32_t(&pTempl->storeCount);
	NETuint32_t(&pTempl->numWeaps);
	NETbool(&pTempl->stored);	// other players don't need to know, but we need to keep the knowledge in the loop somehow...

	for (int i = 0; i < DROID_MAXWEAPS; ++i)
	{
		NETuint32_t(&pTempl->asWeaps[i]);
	}

	NETenum(&pTempl->droidType);
	NETuint32_t(&pTempl->multiPlayerID);
}
Example #13
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;
}
// ////////////////////////////////////////////////////////////////////////////
BOOL recvBuildFinished()
{
    uint32_t	structId;
    STRUCTURE	*psStruct;
    int32_t		x,y,z;
    uint32_t	type,typeindex;
    uint8_t		player;
    uint32_t	power;

    NETbeginDecode(NET_BUILDFINISHED);
    NETuint32_t(&power);	// get the player's power level
    NETuint32_t(&structId);	// get the struct id.
    NETuint32_t(&type); 	// Kind of building.
    NETint32_t(&x);    	// x pos
    NETint32_t(&y);    	// y pos
    NETint32_t(&z);    	// z pos
    NETuint8_t(&player);
    NETend();

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

    psStruct = IdToStruct(structId,ANYPLAYER);
    setPower( (uint32_t)player, power);		// we sync the power level as well

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

        if (psStruct->status != SS_BUILT)
        {
            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(x), map_coord(y))))
    {
        // Get the current structure
        psStruct = getTileStructure(map_coord(x), map_coord(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]), x, y, player, true);

    if (psStruct)
    {
        psStruct->id		= structId;
        psStruct->status	= SS_BUILT;
        buildingComplete(psStruct);
        debug(LOG_SYNC, "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, "Unable to create building for player %u", player);
        NETlogEntry("had to plonk down a building, BUT FAILED!" , SYNC_FLAG, player);
    }

    return false;
}
// ////////////////////////////////////////////////////////////////////////////
// put down a base plate and start droid building it!
BOOL recvBuildStarted()
{
    STRUCTURE_STATS *psStats;
    DROID			*psDroid;
    UDWORD			actionX,actionY;
    unsigned int typeIndex;
    uint8_t			player;
    uint16_t		x, y, z;
    int32_t			order;
    uint32_t		structRef, structId, targetId,droidID;

    NETbeginDecode(NET_BUILD);
    NETuint8_t(&player);
    NETuint32_t(&structRef);
    NETuint16_t(&x);
    NETuint16_t(&y);
    NETuint32_t(&droidID);
    NETuint32_t(&structId);
    NETint32_t(&order);
    NETuint32_t(&targetId);
    NETuint16_t(&z);
    NETend();
    // Find structure target
    for (typeIndex = 0;
            typeIndex < numStructureStats && asStructureStats[typeIndex].ref != structRef;
            typeIndex++);

    psStats = &asStructureStats[typeIndex];

    if (IdToDroid(droidID, player, &psDroid))
    {
        // Tell the droid to go to where it needs to in order to build the struct
        if (getDroidDestination((BASE_STATS *) psStats, x, y, &actionX, &actionY))
        {
            psDroid->order = order;

            if (psDroid->order == DORDER_LINEBUILD)
            {
                psDroid->order = DORDER_BUILD;
            }

            psDroid->orderX = x;
            psDroid->orderY = y;
            psDroid->psTarStats = (BASE_STATS *) psStats;

            if (targetId)
            {
                setDroidTarget(psDroid, IdToPointer(targetId, ANYPLAYER));
            }
            else
            {
                setDroidTarget(psDroid, NULL);
            }

            if (IsStatExpansionModule(psStats))
            {
                setUpBuildModule(psDroid);
            }
            else
            {
                droidStartBuild(psDroid);
                psDroid->action = DACTION_BUILD;
            }
        }

        // Sync IDs
        if (psDroid->psTarget)
        {
            ((STRUCTURE *) psDroid->psTarget)->id = structId;
        }
    }

    return true;
}
Example #16
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;
}
Example #17
0
BOOL NETPosition(Position *vp)
{
	return (NETint32_t(&vp->x)
	     && NETint32_t(&vp->y)
	     && NETint32_t(&vp->z));
}