Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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 Cyp authored
View
43 src/multiplay.cpp
@@ -928,6 +928,21 @@ bool sendResearchStatus(STRUCTURE *psBuilding, uint32_t index, uint8_t player, b
return true;
}
+STRUCTURE *findResearchingFacilityByResearchIndex(unsigned player, unsigned index)
+{
+ // Go through the structs to find the one doing this topic
+ for (STRUCTURE *psBuilding = apsStructLists[player]; psBuilding; psBuilding = psBuilding->psNext)
+ {
+ if (psBuilding->pStructureType->type == REF_RESEARCH
+ && ((RESEARCH_FACILITY *)psBuilding->pFunctionality)->psSubject
+ && ((RESEARCH_FACILITY *)psBuilding->pFunctionality)->psSubject->ref - REF_RESEARCH_START == index)
+ {
+ return psBuilding;
+ }
+ }
+ return NULL; // Not found.
+}
+
bool recvResearchStatus(NETQUEUE queue)
{
STRUCTURE *psBuilding;
@@ -986,6 +1001,22 @@ bool recvResearchStatus(NETQUEUE queue)
cancelResearch(psBuilding, ModeImmediate);
}
+ if (IsResearchStarted(pPlayerRes))
+ {
+ STRUCTURE *psOtherBuilding = findResearchingFacilityByResearchIndex(player, index);
+ ASSERT(psOtherBuilding != NULL, "Something researched but no facility.");
+ if (psOtherBuilding != NULL)
+ {
+ cancelResearch(psOtherBuilding, ModeImmediate);
+ }
+ }
+
+ if (!researchAvailable(index, player, ModeImmediate) && bMultiPlayer)
+ {
+ debug(LOG_ERROR, "Player %d researching impossible topic \"%s\".", player, asResearch[index].pName);
+ return false;
+ }
+
// Set the subject up
pResearch = &asResearch[index];
psResFacilty->psSubject = pResearch;
@@ -1007,17 +1038,7 @@ bool recvResearchStatus(NETQUEUE queue)
// If they did not say what facility it was, look it up orselves
if (!structRef)
{
- // Go through the structs to find the one doing this topic
- for (psBuilding = apsStructLists[player]; psBuilding; psBuilding = psBuilding->psNext)
- {
- if (psBuilding->pStructureType->type == REF_RESEARCH
- && psBuilding->status == SS_BUILT
- && ((RESEARCH_FACILITY *) psBuilding->pFunctionality)->psSubject
- && ((RESEARCH_FACILITY *) psBuilding->pFunctionality)->psSubject->ref - REF_RESEARCH_START == index)
- {
- break;
- }
- }
+ psBuilding = findResearchingFacilityByResearchIndex(player, index);
}
else
{
View
2  src/multiplay.h
@@ -231,4 +231,6 @@ extern bool multiplayPlayersReady (bool bNotifyStatus);
extern void startMultiplayerGame (void);
extern void resetReadyStatus (bool bSendOptions);
+STRUCTURE *findResearchingFacilityByResearchIndex(unsigned player, unsigned index);
+
#endif // __INCLUDED_SRC_MULTIPLAY_H__
View
4 src/qtscriptfuncs.cpp
@@ -574,7 +574,7 @@ static QScriptValue js_pursueResearch(QScriptContext *context, QScriptEngine *en
int iterations = 0; // Only used to assert we're not stuck in the loop.
while (cur)
{
- if (researchAvailable(cur->index, player))
+ if (researchAvailable(cur->index, player, ModeQueue))
{
bool started = false;
for (int i = 0; i < game.maxPlayers; i++)
@@ -644,7 +644,7 @@ static QScriptValue js_enumResearch(QScriptContext *context, QScriptEngine *engi
for (int i = 0; i < asResearch.size(); i++)
{
RESEARCH *psResearch = &asResearch[i];
- if (!IsResearchCompleted(&asPlayerResList[player][i]) && researchAvailable(i, player))
+ if (!IsResearchCompleted(&asPlayerResList[player][i]) && researchAvailable(i, player, ModeQueue))
{
reslist += psResearch;
}
View
29 src/research.cpp
@@ -597,13 +597,22 @@ bool loadResearchFunctions(const char *pFunctionData, UDWORD bufferSize)
return true;
}
-bool researchAvailable(int inc, int playerID)
+bool researchAvailable(int inc, int playerID, QUEUE_MODE mode)
{
+ // Decide whether to use IsResearchCancelledPending/IsResearchStartedPending or IsResearchCancelled/IsResearchStarted.
+ bool (*IsResearchCancelledFunc)(PLAYER_RESEARCH const *) = IsResearchCancelledPending;
+ bool (*IsResearchStartedFunc)(PLAYER_RESEARCH const *) = IsResearchStartedPending;
+ if (mode == ModeImmediate)
+ {
+ IsResearchCancelledFunc = IsResearchCancelled;
+ IsResearchStartedFunc = IsResearchStarted;
+ }
+
UDWORD incPR, incS;
bool bPRFound, bStructFound;
// if its a cancelled topic - add to list
- if (IsResearchCancelledPending(&asPlayerResList[playerID][inc]))
+ if (IsResearchCancelledFunc(&asPlayerResList[playerID][inc]))
{
return true;
}
@@ -611,7 +620,7 @@ bool researchAvailable(int inc, int playerID)
if ((IsResearchPossible(&asPlayerResList[playerID][inc])))
{
if (!IsResearchCompleted(&asPlayerResList[playerID][inc])
- && !IsResearchStartedPending(&asPlayerResList[playerID][inc]))
+ && !IsResearchStartedFunc(&asPlayerResList[playerID][inc]))
{
return true;
}
@@ -623,8 +632,18 @@ bool researchAvailable(int inc, int playerID)
return false;
}
+ bool researchStarted = IsResearchStartedFunc(&asPlayerResList[playerID][inc]);
+ if (researchStarted)
+ {
+ STRUCTURE *psBuilding = findResearchingFacilityByResearchIndex(playerID, inc); // May fail to find the structure here, if the research is merely pending, not actually started.
+ if (psBuilding != NULL && psBuilding->status == SS_BEING_BUILT)
+ {
+ researchStarted = false; // Although research is started, the facility is currently being upgraded or demolished, so we want to be able to research this elsewhere.
+ }
+ }
+
// make sure that the research is not completed or started by another researchfac
- if (!IsResearchCompleted(&asPlayerResList[playerID][inc]) && !IsResearchStartedPending(&asPlayerResList[playerID][inc]))
+ if (!IsResearchCompleted(&asPlayerResList[playerID][inc]) && !researchStarted)
{
// Research is not completed ... also it has not been started by another researchfac
@@ -695,7 +714,7 @@ UWORD fillResearchList(UWORD *plist, UDWORD playerID, UWORD topic, UWORD limit)
for (inc=0; inc < asResearch.size(); inc++)
{
// if the inc matches the 'topic' - automatically add to the list
- if (inc == topic || researchAvailable(inc, playerID))
+ if (inc == topic || researchAvailable(inc, playerID, ModeQueue))
{
*plist++ = inc;
count++;
View
2  src/research.h
@@ -149,6 +149,6 @@ void CancelAllResearch(UDWORD pl);
extern bool researchInitVars(void);
-bool researchAvailable(int inc, int playerID);
+bool researchAvailable(int inc, int playerID, QUEUE_MODE mode);
#endif // __INCLUDED_SRC_RESEARCH_H__
Please sign in to comment.
Something went wrong with that request. Please try again.