Exemple #1
0
// ////////////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////////////
// Power Checking. Send a power level check every now and again.
static BOOL sendPowerCheck()
{
	uint8_t         player;

	if (powerCheckLastSent > gameTime)
	{
		powerCheckLastSent = 0;
	}

	// Only send if not done recently
	if (gameTime - powerCheckLastSent < POWER_PERIOD)
	{
		return true;
	}

	powerCheckLastSent = gameTime;
	for (player = 0; player < MAX_PLAYERS; ++player)
	{
		powerCheckLastPower[player] = getPrecisePower(player);
		if (myResponsibility(player))
		{
			if (!isInSync())  // Don't really send anything, unless out of synch.
			{
				NETbeginEncode(NETgameQueue(selectedPlayer), GAME_CHECK_POWER);
					NETuint8_t(&player);
					NETuint32_t(&gameTime);
					NETint64_t(&powerCheckLastPower[player]);
				NETend();
			}
		}
	}
	return true;
}
void CCovarianceFunctionCacheOld::validateCache()
{
	if (!isInSync())
	{
		KCacheNull = true;
		SVDCacheNull = true;
		cholKCacheNull = true;
		//set sync
	}
	setSync();
}
Exemple #3
0
static void gameStateUpdate()
{
	// Can't dump isHumanPlayer, since it causes spurious desynch dumps when players leave.
	// TODO isHumanPlayer should probably be synchronised, since the game state seems to depend on it, so there might also be a risk of real desynchs when players leave.
	//syncDebug("map = \"%s\", humanPlayers = %d %d %d %d %d %d %d %d", game.map, isHumanPlayer(0), isHumanPlayer(1), isHumanPlayer(2), isHumanPlayer(3), isHumanPlayer(4), isHumanPlayer(5), isHumanPlayer(6), isHumanPlayer(7));
	syncDebug("map = \"%s\"", game.map);

	// Actually send pending droid orders.
	sendQueuedDroidInfo();

	sendPlayerGameTime();
	gameSRand(gameTime);   // Brute force way of synchronising the random number generator, which can't go out of synch.

	if (!paused && !scriptPaused() && !editPaused())
	{
		/* Update the event system */
		if (!bInTutorial)
		{
			eventProcessTriggers(gameTime/SCR_TICKRATE);
		}
		else
		{
			eventProcessTriggers(realTime/SCR_TICKRATE);
		}
		updateScripts();
	}

	// Update abandoned structures
	handleAbandonedStructures();

	// Update the visibility change stuff
	visUpdateLevel();

	// Put all droids/structures/features into the grid.
	gridReset();

	// Check which objects are visible.
	processVisibility();

	// Update the map.
	mapUpdate();

	//update the findpath system
	fpathUpdate();

	// update the cluster system
	clusterUpdate();

	// update the command droids
	cmdDroidUpdate();
	if(getDrivingStatus())
	{
		driveUpdate();
	}

	fireWaitingCallbacks(); //Now is the good time to fire waiting callbacks (since interpreter is off now)

	for (unsigned i = 0; i < MAX_PLAYERS; i++)
	{
		//update the current power available for a player
		updatePlayerPower(i);

		//set the flag for each player
		setHQExists(false, i);
		setSatUplinkExists(false, i);

		numCommandDroids[i] = 0;
		numConstructorDroids[i] = 0;
		numDroids[i]=0;
		numTransporterDroids[i]=0;

		DROID *psNext;
		for (DROID *psCurr = apsDroidLists[i]; psCurr != NULL; psCurr = psNext)
		{
			// Copy the next pointer - not 100% sure if the droid could get destroyed but this covers us anyway
			psNext = psCurr->psNext;
			droidUpdate(psCurr);

			// update the droid counts
			numDroids[i]++;
			switch (psCurr->droidType)
			{
				case DROID_COMMAND:
					numCommandDroids[i] += 1;
					break;
				case DROID_CONSTRUCT:
				case DROID_CYBORG_CONSTRUCT:
					numConstructorDroids[i] += 1;
					break;
				case DROID_TRANSPORTER:
					if( (psCurr->psGroup != NULL) )
					{
						DROID *psDroid = NULL;

						numTransporterDroids[i] += psCurr->psGroup->refCount-1;
						// and count the units inside it...
							for (psDroid = psCurr->psGroup->psList; psDroid != NULL && psDroid != psCurr; psDroid = psDroid->psGrpNext)
							{
							if (psDroid->droidType == DROID_CYBORG_CONSTRUCT || psDroid->droidType == DROID_CONSTRUCT)
								{
									numConstructorDroids[i] += 1;
								}
							if (psDroid->droidType == DROID_COMMAND)
							{
								numCommandDroids[i] += 1;
							}
						}
					}
					break;
				default:
					break;
			}
		}

		numMissionDroids[i]=0;
		for (DROID *psCurr = mission.apsDroidLists[i]; psCurr != NULL; psCurr = psNext)
		{
			/* Copy the next pointer - not 100% sure if the droid could
			get destroyed but this covers us anyway */
			psNext = psCurr->psNext;
			missionDroidUpdate(psCurr);
			numMissionDroids[i]++;
			switch (psCurr->droidType)
			{
				case DROID_COMMAND:
					numCommandDroids[i] += 1;
					break;
				case DROID_CONSTRUCT:
				case DROID_CYBORG_CONSTRUCT:
					numConstructorDroids[i] += 1;
					break;
				case DROID_TRANSPORTER:
					if( (psCurr->psGroup != NULL) )
					{
						numTransporterDroids[i] += psCurr->psGroup->refCount-1;
					}
					break;
				default:
					break;
			}
		}
		for (DROID *psCurr = apsLimboDroids[i]; psCurr != NULL; psCurr = psNext)
		{
			/* Copy the next pointer - not 100% sure if the droid could
			get destroyed but this covers us anyway */
			psNext = psCurr->psNext;

			// count the type of units
			switch (psCurr->droidType)
			{
				case DROID_COMMAND:
					numCommandDroids[i] += 1;
					break;
				case DROID_CONSTRUCT:
				case DROID_CYBORG_CONSTRUCT:
					numConstructorDroids[i] += 1;
					break;
				default:
					break;
			}
		}

		// FIXME: These for-loops are code duplicationo
		/*set this up AFTER droidUpdate so that if trying to building a
		new one, we know whether one exists already*/
		setLasSatExists(false, i);
		STRUCTURE *psNBuilding;
		for (STRUCTURE *psCBuilding = apsStructLists[i]; psCBuilding != NULL; psCBuilding = psNBuilding)
		{
			/* Copy the next pointer - not 100% sure if the structure could get destroyed but this covers us anyway */
			psNBuilding = psCBuilding->psNext;
			structureUpdate(psCBuilding, false);
			//set animation flag
			if (psCBuilding->pStructureType->type == REF_HQ &&
				psCBuilding->status == SS_BUILT)
			{
				setHQExists(true, i);
			}
			if (psCBuilding->pStructureType->type == REF_SAT_UPLINK &&
				psCBuilding->status == SS_BUILT)
			{
				setSatUplinkExists(true, i);
			}
			//don't wait for the Las Sat to be built - can't build another if one is partially built
			if (asWeaponStats[psCBuilding->asWeaps[0].nStat].
				weaponSubClass == WSC_LAS_SAT)
			{
				setLasSatExists(true, i);
			}
		}
		for (STRUCTURE *psCBuilding = mission.apsStructLists[i]; psCBuilding != NULL; psCBuilding = psNBuilding)
		{
			/* Copy the next pointer - not 100% sure if the structure could get destroyed but this covers us anyway. It shouldn't do since its not even on the map!*/
			psNBuilding = psCBuilding->psNext;
			structureUpdate(psCBuilding, true); // update for mission
			if (psCBuilding->pStructureType->type == REF_HQ &&
				psCBuilding->status == SS_BUILT)
			{
				setHQExists(true, i);
			}
			if (psCBuilding->pStructureType->type == REF_SAT_UPLINK &&
				psCBuilding->status == SS_BUILT)
			{
				setSatUplinkExists(true, i);
			}
			//don't wait for the Las Sat to be built - can't build another if one is partially built
			if (asWeaponStats[psCBuilding->asWeaps[0].nStat].
				weaponSubClass == WSC_LAS_SAT)
			{
				setLasSatExists(true, i);
			}
		}
	}

	missionTimerUpdate();

	proj_UpdateAll();

	FEATURE *psNFeat;
	for (FEATURE *psCFeat = apsFeatureLists[0]; psCFeat; psCFeat = psNFeat)
	{
		psNFeat = psCFeat->psNext;
		featureUpdate(psCFeat);
	}

	objmemUpdate();

	// Do completely useless stuff.
	if (!isInSync())
	{
		sendCheck();  // send some pointless checking info if we're doomed anyway
	}


	// Must end update, since we may or may not have ticked, and some message queue processing code may vary depending on whether it's in an update.
	gameTimeUpdateEnd();
}
Exemple #4
0
// ////////////////////////////////////////////////////////////////////////
// Send structure information.
static BOOL sendStructureCheck(void)
{
	uint8_t         player;

	if (structureCheckLastSent > gameTime)
	{
		structureCheckLastSent = 0;
	}
	// Only send a struct send if not done recently
	if (gameTime - structureCheckLastSent < STRUCT_PERIOD)
	{
		return true;
	}

	structureCheckLastSent = gameTime;

	for (player = 0; player < MAX_PLAYERS; ++player)
	{
		STRUCTURE       *pS = pickAStructure(player);
		bool            hasCapacity = true;
		uint8_t         capacity;

		// Only send info about complete buildings
		if (pS == NULL || pS->status != SS_BUILT)
		{
			structureCheckLastId[player] = 0;
			continue;
		}

		switch (pS->pStructureType->type)
		{
			case REF_RESEARCH:
				capacity = pS->pFunctionality->researchFacility.capacity;
				break;
			case REF_FACTORY:
			case REF_VTOL_FACTORY:
				capacity = pS->pFunctionality->factory.capacity;
				break;
			case REF_POWER_GEN:
				capacity = pS->pFunctionality->powerGenerator.capacity;
			default:
				hasCapacity = false;
				break;
		}
		structureCheckLastId[player] = pS->id;
		structureCheckLastBody[player] = pS->body;
		structureCheckLastDirection[player] = pS->rot;
		structureCheckLastType[player] = pS->pStructureType->type;

		if (myResponsibility(player))
		{
			if (!isInSync())  // Don't really send anything, unless out of synch.
			{
				NETbeginEncode(NETgameQueue(selectedPlayer), GAME_CHECK_STRUCT);
					NETuint8_t(&player);
					NETuint32_t(&gameTime);
					NETuint32_t(&pS->id);
					NETuint32_t(&pS->body);
					NETuint32_t(&pS->pStructureType->type);
					NETRotation(&pS->rot);
					if (hasCapacity)
					{
						NETuint8_t(&capacity);
					}
				NETend();
			}
		}
	}

	return true;
}
Exemple #5
0
// ///////////////////////////////////////////////////////////////////////////
// send a droid info packet.
static BOOL sendDroidCheck(void)
{
	DROID			*pD, **ppD;
	uint8_t			i, count;
	static UDWORD	lastSent = 0;		// Last time a struct was sent.
	UDWORD			toSend = 12;

	if (lastSent > gameTime)
	{
		lastSent= 0;
	}

	// Only send a struct send if not done recently
	if (gameTime - lastSent < DROID_PERIOD)
	{
		return true;
	}

	lastSent = gameTime;


	if (!isInSync())  // Don't really send anything, unless out of synch.
	{
		NETbeginEncode(NETgameQueue(selectedPlayer), GAME_CHECK_DROID);
	}

		// Allocate space for the list of droids to send
		ppD = alloca(sizeof(DROID *) * toSend);

		// Get the list of droids to sent
		for (i = 0, count = 0; i < toSend; i++)
		{
			pD = pickADroid();

			if (pD == NULL || (pD->gameCheckDroid != NULL && ((PACKAGED_CHECK *)pD->gameCheckDroid)->gameTime > gameTime))
			{
				continue;  // Didn't find a droid, or droid was synched recently.
			}

			// If the droid is ours add it to the list
			if (myResponsibility(pD->player))
			{
				ppD[count++] = pD;
			}
			free(pD->gameCheckDroid);
			pD->gameCheckDroid = (PACKAGED_CHECK *)malloc(sizeof(PACKAGED_CHECK));
			*(PACKAGED_CHECK *)pD->gameCheckDroid = packageCheck(pD);
		}

		if (!isInSync())  // Don't really send anything, unless out of synch.
		{
			// Send the number of droids to expect
			NETuint8_t(&count);
			NETuint32_t(&gameTime);  // Send game time.

			// Add the droids to the packet
			for (i = 0; i < count; i++)
			{
				NETPACKAGED_CHECK((PACKAGED_CHECK *)ppD[i]->gameCheckDroid);
			}
		}

	if (!isInSync())  // Don't really send anything, unless out of synch.
	{
		return NETend();
	}

	return true;
}