Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Allow researching topics which labs being upgraded are already resear…

…ching.

If researching Kittens Mk2 in lab A, then Kittens Mk2 is unavailable for research in other labs. If upgrading lab
A, then Kittens Mk2 now becomes available for research in other labs, for the duration of lab A's upgrade. If
choosing Kittens Mk2 in lab B, then the research of Kittens Mk2 is cancelled in lab A, and the user must manually
select a new research topic for the lab, such as Puppies Mk3. Otherwise, lab A continues researching Kittens Mk2
once lab A is done upgrading, as usual. The same applies if lab A is being demolished, except that lab A cannot
continue researching after it has been demolished.

This is especially useful in the case of a lab upgrade being delayed due to loss of trucks.
  • Loading branch information...
commit 5bac6e4273fbdbd43acaf4a0042b373d4c9dec7c 1 parent 0d333a1
Cyp authored August 21, 2012
43  src/multiplay.cpp
@@ -928,6 +928,21 @@ bool sendResearchStatus(STRUCTURE *psBuilding, uint32_t index, uint8_t player, b
928 928
 	return true;
929 929
 }
930 930
 
  931
+STRUCTURE *findResearchingFacilityByResearchIndex(unsigned player, unsigned index)
  932
+{
  933
+	// Go through the structs to find the one doing this topic
  934
+	for (STRUCTURE *psBuilding = apsStructLists[player]; psBuilding; psBuilding = psBuilding->psNext)
  935
+	{
  936
+		if (psBuilding->pStructureType->type == REF_RESEARCH
  937
+		 && ((RESEARCH_FACILITY *)psBuilding->pFunctionality)->psSubject
  938
+		 && ((RESEARCH_FACILITY *)psBuilding->pFunctionality)->psSubject->ref - REF_RESEARCH_START == index)
  939
+		{
  940
+			return psBuilding;
  941
+		}
  942
+	}
  943
+	return NULL;  // Not found.
  944
+}
  945
+
931 946
 bool recvResearchStatus(NETQUEUE queue)
932 947
 {
933 948
 	STRUCTURE			*psBuilding;
@@ -986,6 +1001,22 @@ bool recvResearchStatus(NETQUEUE queue)
986 1001
 				cancelResearch(psBuilding, ModeImmediate);
987 1002
 			}
988 1003
 
  1004
+			if (IsResearchStarted(pPlayerRes))
  1005
+			{
  1006
+				STRUCTURE *psOtherBuilding = findResearchingFacilityByResearchIndex(player, index);
  1007
+				ASSERT(psOtherBuilding != NULL, "Something researched but no facility.");
  1008
+				if (psOtherBuilding != NULL)
  1009
+				{
  1010
+					cancelResearch(psOtherBuilding, ModeImmediate);
  1011
+				}
  1012
+			}
  1013
+
  1014
+			if (!researchAvailable(index, player, ModeImmediate) && bMultiPlayer)
  1015
+			{
  1016
+				debug(LOG_ERROR, "Player %d researching impossible topic \"%s\".", player, asResearch[index].pName);
  1017
+				return false;
  1018
+			}
  1019
+
989 1020
 			// Set the subject up
990 1021
 			pResearch				= &asResearch[index];
991 1022
 			psResFacilty->psSubject = pResearch;
@@ -1007,17 +1038,7 @@ bool recvResearchStatus(NETQUEUE queue)
1007 1038
 		// If they did not say what facility it was, look it up orselves
1008 1039
 		if (!structRef)
1009 1040
 		{
1010  
-			// Go through the structs to find the one doing this topic
1011  
-			for (psBuilding = apsStructLists[player]; psBuilding; psBuilding = psBuilding->psNext)
1012  
-			{
1013  
-				if (psBuilding->pStructureType->type == REF_RESEARCH
1014  
-				 && psBuilding->status == SS_BUILT
1015  
-				 && ((RESEARCH_FACILITY *) psBuilding->pFunctionality)->psSubject
1016  
-				 && ((RESEARCH_FACILITY *) psBuilding->pFunctionality)->psSubject->ref - REF_RESEARCH_START == index)
1017  
-				{
1018  
-					break;
1019  
-				}
1020  
-			}
  1041
+			psBuilding = findResearchingFacilityByResearchIndex(player, index);
1021 1042
 		}
1022 1043
 		else
1023 1044
 		{
2  src/multiplay.h
@@ -231,4 +231,6 @@ extern	bool multiplayPlayersReady	(bool bNotifyStatus);
231 231
 extern	void startMultiplayerGame	(void);
232 232
 extern	void resetReadyStatus		(bool bSendOptions);
233 233
 
  234
+STRUCTURE *findResearchingFacilityByResearchIndex(unsigned player, unsigned index);
  235
+
234 236
 #endif // __INCLUDED_SRC_MULTIPLAY_H__
4  src/qtscriptfuncs.cpp
@@ -574,7 +574,7 @@ static QScriptValue js_pursueResearch(QScriptContext *context, QScriptEngine *en
574 574
 	int iterations = 0;  // Only used to assert we're not stuck in the loop.
575 575
 	while (cur)
576 576
 	{
577  
-		if (researchAvailable(cur->index, player))
  577
+		if (researchAvailable(cur->index, player, ModeQueue))
578 578
 		{
579 579
 			bool started = false;
580 580
 			for (int i = 0; i < game.maxPlayers; i++)
@@ -644,7 +644,7 @@ static QScriptValue js_enumResearch(QScriptContext *context, QScriptEngine *engi
644 644
 	for (int i = 0; i < asResearch.size(); i++)
645 645
 	{
646 646
 		RESEARCH *psResearch = &asResearch[i];
647  
-		if (!IsResearchCompleted(&asPlayerResList[player][i]) && researchAvailable(i, player))
  647
+		if (!IsResearchCompleted(&asPlayerResList[player][i]) && researchAvailable(i, player, ModeQueue))
648 648
 		{
649 649
 			reslist += psResearch;
650 650
 		}
29  src/research.cpp
@@ -597,13 +597,22 @@ bool loadResearchFunctions(const char *pFunctionData, UDWORD bufferSize)
597 597
 	return true;
598 598
 }
599 599
 
600  
-bool researchAvailable(int inc, int playerID)
  600
+bool researchAvailable(int inc, int playerID, QUEUE_MODE mode)
601 601
 {
  602
+	// Decide whether to use IsResearchCancelledPending/IsResearchStartedPending or IsResearchCancelled/IsResearchStarted.
  603
+	bool (*IsResearchCancelledFunc)(PLAYER_RESEARCH const *) = IsResearchCancelledPending;
  604
+	bool (*IsResearchStartedFunc)(PLAYER_RESEARCH const *) = IsResearchStartedPending;
  605
+	if (mode == ModeImmediate)
  606
+	{
  607
+		IsResearchCancelledFunc = IsResearchCancelled;
  608
+		IsResearchStartedFunc = IsResearchStarted;
  609
+	}
  610
+
602 611
 	UDWORD				incPR, incS;
603 612
 	bool				bPRFound, bStructFound;
604 613
 
605 614
 	// if its a cancelled topic - add to list
606  
-	if (IsResearchCancelledPending(&asPlayerResList[playerID][inc]))
  615
+	if (IsResearchCancelledFunc(&asPlayerResList[playerID][inc]))
607 616
 	{
608 617
 		return true;
609 618
 	}
@@ -611,7 +620,7 @@ bool researchAvailable(int inc, int playerID)
611 620
 	if ((IsResearchPossible(&asPlayerResList[playerID][inc])))
612 621
 	{
613 622
 		if (!IsResearchCompleted(&asPlayerResList[playerID][inc])
614  
-		    && !IsResearchStartedPending(&asPlayerResList[playerID][inc]))
  623
+		    && !IsResearchStartedFunc(&asPlayerResList[playerID][inc]))
615 624
 		{
616 625
 			return true;
617 626
 		}
@@ -623,8 +632,18 @@ bool researchAvailable(int inc, int playerID)
623 632
 		return false;
624 633
 	}
625 634
 
  635
+	bool researchStarted = IsResearchStartedFunc(&asPlayerResList[playerID][inc]);
  636
+	if (researchStarted)
  637
+	{
  638
+		STRUCTURE *psBuilding = findResearchingFacilityByResearchIndex(playerID, inc);  // May fail to find the structure here, if the research is merely pending, not actually started.
  639
+		if (psBuilding != NULL && psBuilding->status == SS_BEING_BUILT)
  640
+		{
  641
+			researchStarted = false;  // Although research is started, the facility is currently being upgraded or demolished, so we want to be able to research this elsewhere.
  642
+		}
  643
+	}
  644
+
626 645
 	// make sure that the research is not completed  or started by another researchfac
627  
-	if (!IsResearchCompleted(&asPlayerResList[playerID][inc]) && !IsResearchStartedPending(&asPlayerResList[playerID][inc]))
  646
+	if (!IsResearchCompleted(&asPlayerResList[playerID][inc]) && !researchStarted)
628 647
 	{
629 648
 		// Research is not completed  ... also  it has not been started by another researchfac
630 649
 
@@ -695,7 +714,7 @@ UWORD fillResearchList(UWORD *plist, UDWORD playerID, UWORD topic, UWORD limit)
695 714
 	for (inc=0; inc < asResearch.size(); inc++)
696 715
 	{
697 716
 		// if the inc matches the 'topic' - automatically add to the list
698  
-		if (inc == topic || researchAvailable(inc, playerID))
  717
+		if (inc == topic || researchAvailable(inc, playerID, ModeQueue))
699 718
 		{
700 719
 			*plist++ = inc;
701 720
 			count++;
2  src/research.h
@@ -149,6 +149,6 @@ void CancelAllResearch(UDWORD pl);
149 149
 
150 150
 extern bool researchInitVars(void);
151 151
 
152  
-bool researchAvailable(int inc, int playerID);
  152
+bool researchAvailable(int inc, int playerID, QUEUE_MODE mode);
153 153
 
154 154
 #endif // __INCLUDED_SRC_RESEARCH_H__

0 notes on commit 5bac6e4

Please sign in to comment.
Something went wrong with that request. Please try again.