Exemplo n.º 1
0
// recv a research topic that is now complete.
static bool recvResearch(NETQUEUE queue)
{
	uint8_t			player;
	uint32_t		index;
	int				i;
	PLAYER_RESEARCH	*pPlayerRes;

	NETbeginDecode(queue, GAME_DEBUG_FINISH_RESEARCH);
		NETuint8_t(&player);
		NETuint32_t(&index);
	NETend();

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

	syncDebug("player%d, index%u", player, index);

	if (player >= MAX_PLAYERS || index >= asResearch.size())
	{
		debug(LOG_ERROR, "Bad GAME_DEBUG_FINISH_RESEARCH received, player is %d, index is %u", (int)player, index);
		return false;
	}

	pPlayerRes = &asPlayerResList[player][index];
	syncDebug("research status = %d", pPlayerRes->ResearchStatus & RESBITS);

	if (!IsResearchCompleted(pPlayerRes))
	{
		MakeResearchCompleted(pPlayerRes);
		researchResult(index, player, false, NULL, true);
	}

	// Update allies research accordingly
	if (game.type == SKIRMISH)
	{
		for (i = 0; i < MAX_PLAYERS; i++)
		{
			if (alliances[i][player] == ALLIANCE_FORMED)
			{
				pPlayerRes = &asPlayerResList[i][index];

				if (!IsResearchCompleted(pPlayerRes))
				{
					// Do the research for that player
					MakeResearchCompleted(pPlayerRes);
					researchResult(index, i, false, NULL, true);
				}
			}
		}
	}

	return true;
}
Exemplo n.º 2
0
// ////////////////////////////////////////////////////////////////////////////
// give technologies.
static void giftResearch(uint8_t from, uint8_t to, bool send)
{
	int		i;
	uint32_t	dummy = 0;

	if (send)
	{
		uint8_t giftType = RESEARCH_GIFT;

		NETbeginEncode(NETgameQueue(selectedPlayer), GAME_GIFT);
		NETuint8_t(&giftType);
		NETuint8_t(&from);
		NETuint8_t(&to);
		NETuint32_t(&dummy);
		NETend();
	}
	else if (alliancesCanGiveResearchAndRadar(game.alliance))
	{
		if (to == selectedPlayer)
		{
			CONPRINTF(ConsoleString, (ConsoleString, _("%s Gives You Technology Documents"), getPlayerName(from)));
		}
		// For each topic
		for (i = 0; i < asResearch.size(); i++)
		{
			// If they have it and we don't research it
			if (IsResearchCompleted(&asPlayerResList[from][i])
			    && !IsResearchCompleted(&asPlayerResList[to][i]))
			{
				MakeResearchCompleted(&asPlayerResList[to][i]);
				researchResult(i, to, false, NULL, true);
			}
		}
	}
}
Exemplo n.º 3
0
// ////////////////////////////////////////////////////////////////////////////
// give technologies.
static void giftResearch(uint8_t from, uint8_t to, BOOL send)
{
	PLAYER_RESEARCH	*pR, *pRto;
	int		i;
	uint32_t	dummy = 0;

	if (send)
	{
		uint8_t giftType = RESEARCH_GIFT;

		NETbeginEncode(NETgameQueue(selectedPlayer), GAME_GIFT);
			NETuint8_t(&giftType);
			NETuint8_t(&from);
			NETuint8_t(&to);
			NETuint32_t(&dummy);
		NETend();
	}
	else
	{
		if (to == selectedPlayer)
		{
			CONPRINTF(ConsoleString, (ConsoleString, _("%s Gives You Technology Documents"), getPlayerName(from)));
		}
		pR   = asPlayerResList[from];
		pRto = asPlayerResList[to];

		// For each topic
		for (i = 0; i < numResearch; i++)
		{
			// If they have it and we don't research it
			if (IsResearchCompleted(&pR[i])
			&& !IsResearchCompleted(&pRto[i]))
			{
				MakeResearchCompleted(&pRto[i]);
				researchResult(i, to, false, NULL, true);
			}
		}
	}
}
Exemplo n.º 4
0
/* process the results of a completed research topic */
void researchResult(UDWORD researchIndex, UBYTE player, bool bDisplay, STRUCTURE *psResearchFacility, bool bTrigger)
{
	RESEARCH                                       *pResearch = &asResearch[researchIndex];
	MESSAGE						*pMessage;
	//the message gets sent to console
	char						consoleMsg[MAX_RESEARCH_MSG_SIZE];

	ASSERT_OR_RETURN(, researchIndex < asResearch.size(), "Invalid research index %u", researchIndex);

	syncDebug("researchResult(%u, %u, …)", researchIndex, player);

	MakeResearchCompleted(&asPlayerResList[player][researchIndex]);

	//check for structures to be made available
	for (unsigned short pStructureResult : pResearch->pStructureResults)
	{
		if (apStructTypeLists[player][pStructureResult] != REDUNDANT)
		{
			apStructTypeLists[player][pStructureResult] = AVAILABLE;
		}
	}

	//check for structures to be made redundant
	for (unsigned short pRedStruct : pResearch->pRedStructs)
	{
		apStructTypeLists[player][pRedStruct] = REDUNDANT;
	}

	//check for component replacement
	if (!pResearch->componentReplacement.empty())
	{
		for (auto &ri : pResearch->componentReplacement)
		{
			COMPONENT_STATS *pOldComp = ri.pOldComponent;
			replaceComponent(ri.pNewComponent, pOldComp, player);
			apCompLists[player][pOldComp->compType][pOldComp->index] = REDUNDANT;
		}
	}

	//check for artefacts to be made available
	for (auto &componentResult : pResearch->componentResults)
	{
		//determine the type of artefact
		COMPONENT_TYPE type = componentResult->compType;
		//set the component state to AVAILABLE
		int compInc = componentResult->index;
		if (apCompLists[player][type][compInc] != REDUNDANT)
		{
			apCompLists[player][type][compInc] = AVAILABLE;
		}
		//check for default sensor
		if (type == COMP_SENSOR && (asSensorStats + compInc)->location == LOC_DEFAULT)
		{
			aDefaultSensor[player] = compInc;
		}
		//check for default ECM
		else if (type == COMP_ECM && (asECMStats + compInc)->location == LOC_DEFAULT)
		{
			aDefaultECM[player] = compInc;
		}
		//check for default Repair
		else if (type == COMP_REPAIRUNIT && (asRepairStats + compInc)->location == LOC_DEFAULT)
		{
			aDefaultRepair[player] = compInc;
			enableSelfRepair(player);
		}
	}

	//check for artefacts to be made redundant
	for (auto &pRedArtefact : pResearch->pRedArtefacts)
	{
		COMPONENT_TYPE type = pRedArtefact->compType;
		apCompLists[player][type][pRedArtefact->index] = REDUNDANT;
	}

	//Add message to player's list if Major Topic
	if ((pResearch->techCode == TC_MAJOR) && bDisplay)
	{
		//only play sound if major topic
		if (player == selectedPlayer)
		{
			audio_QueueTrack(ID_SOUND_MAJOR_RESEARCH);
		}

		//check there is viewdata for the research topic - just don't add message if not!
		if (pResearch->pViewData != nullptr)
		{
			pMessage = addMessage(MSG_RESEARCH, false, player);
			if (pMessage != nullptr)
			{
				pMessage->pViewData = pResearch->pViewData;
				jsDebugMessageUpdate();
			}
		}
	}
	else if (player == selectedPlayer && bDisplay)
	{
		audio_QueueTrack(ID_SOUND_RESEARCH_COMPLETED);
	}

	if (player == selectedPlayer && bDisplay)
	{
		//add console text message
		if (pResearch->pViewData != nullptr)
		{
			snprintf(consoleMsg, MAX_RESEARCH_MSG_SIZE, _("Research completed: %s"), _(pResearch->pViewData->textMsg[0].toUtf8().c_str()));
			addConsoleMessage(consoleMsg, LEFT_JUSTIFY, SYSTEM_MESSAGE);
		}
		else
		{
			addConsoleMessage(_("Research Completed"), LEFT_JUSTIFY, SYSTEM_MESSAGE);
		}
	}

	if (psResearchFacility)
	{
		psResearchFacility->pFunctionality->researchFacility.psSubject = nullptr;		// Make sure topic is cleared
	}
	if ((bMultiPlayer || player == selectedPlayer) && bTrigger)
	{
		psCBLastResearch = pResearch;  // Fun with pointers. Throw them into some random global variable, and get Nexus to absorb them.
		CBResFacilityOwner = player;
		psCBLastResStructure = psResearchFacility;
		eventFireCallbackTrigger((TRIGGER_TYPE)CALL_RESEARCHCOMPLETED);
		psCBLastResStructure = nullptr;
		CBResFacilityOwner = -1;
		psCBLastResearch = nullptr;
	}
	triggerEventResearched(pResearch, psResearchFacility, player);
}