diff --git a/lib/framework/frame.h b/lib/framework/frame.h index b7ec1bc00..96f405297 100644 --- a/lib/framework/frame.h +++ b/lib/framework/frame.h @@ -55,6 +55,13 @@ extern uint32_t realSelectedPlayer; ///< The player number corresponding to thi #define MAX_PLAYERS 8 /**< Maximum number of players in the game. */ #define MAX_PLAYER_SLOTS 10 /**< 8 players, 1 baba and 1 reserved for features. */ +typedef enum +{ + ModeQueue, ///< Sends a message on the game queue, which will get synchronised, by sending a GAME_ message. + ModeImmediate ///< Performs the action immediately. Must already have been synchronised, for example by sending a GAME_ message. +} QUEUE_MODE; + + /** Initialise the framework library * @param pWindowName the text to appear in the window title bar * @param width the display widget diff --git a/src/design.c b/src/design.c index 813980617..322e0811a 100644 --- a/src/design.c +++ b/src/design.c @@ -4094,11 +4094,7 @@ void intProcessDesign(UDWORD id) /* remove template if found */ if ( psTempl ) { - - if (bMultiMessages) //ajl. inform others of template destruction. - { - SendDestroyTemplate(psTempl); - } + SendDestroyTemplate(psTempl); //update player template list. { diff --git a/src/droid.c b/src/droid.c index eadec8dfa..cc78010e5 100644 --- a/src/droid.c +++ b/src/droid.c @@ -4608,7 +4608,7 @@ static void maybeDeleteTemplateFromProduction(DROID_TEMPLATE *psTemplate, UBYTE //power is returned by factoryProdAdjust() if (psNextTemplate) { - structSetManufacture(psStruct, psNextTemplate); + structSetManufacture(psStruct, psNextTemplate, ModeQueue); // ModeQueue because production lists aren't synchronised. } else { diff --git a/src/hci.c b/src/hci.c index 1f834a7d2..2cb071e8f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -2758,12 +2758,12 @@ static void intProcessObject(UDWORD id) if (StructIsFactory((STRUCTURE *)psObj)) { //might need to cancel the hold on production - releaseProduction((STRUCTURE *)psObj); + releaseProduction((STRUCTURE *)psObj, ModeQueue); } else if (((STRUCTURE *)psObj)->pStructureType->type == REF_RESEARCH) { //might need to cancel the hold on research facilty - releaseResearch((STRUCTURE *)psObj); + releaseResearch((STRUCTURE *)psObj, ModeQueue); } } } @@ -2832,7 +2832,7 @@ static void intProcessStats(UDWORD id) if (!StructureIsManufacturingPending(psStructure)) { - structSetManufacture(psStructure, psNext); + structSetManufacture(psStructure, psNext, ModeQueue); } //need to check if this was the template that was mid-production @@ -2844,7 +2844,7 @@ static void intProcessStats(UDWORD id) if (StructureIsOnHoldPending(psStructure)) { - releaseProduction(psStructure); + releaseProduction(psStructure, ModeQueue); } // Reset the button on the object form @@ -2864,7 +2864,7 @@ static void intProcessStats(UDWORD id) { if (psObjSelected->type == OBJ_STRUCTURE ) { - cancelResearch((STRUCTURE *)psObjSelected); + cancelResearch((STRUCTURE *)psObjSelected, ModeQueue); } } @@ -2889,7 +2889,7 @@ static void intProcessStats(UDWORD id) if (((RESEARCH_FACILITY *)((STRUCTURE *)psObjSelected)-> pFunctionality)->psSubject) { - cancelResearch((STRUCTURE *)psObjSelected); + cancelResearch((STRUCTURE *)psObjSelected, ModeQueue); } } } @@ -6219,7 +6219,7 @@ static BOOL setResearchStats(BASE_OBJECT *psObj, BASE_STATS *psStats) } else { - cancelResearch(psBuilding); + cancelResearch(psBuilding, ModeQueue); } psResFacilty->psSubjectPending = psStats; // Tell UI that we are going to research. //stop the button from flashing once a topic has been chosen @@ -6335,7 +6335,7 @@ static BOOL setManufactureStats(BASE_OBJECT *psObj, BASE_STATS *psStats) if (psStats != NULL) { /* Set the factory to build droid(s) */ - if (!structSetManufacture(Structure, (DROID_TEMPLATE *)psStats)) + if (!structSetManufacture(Structure, (DROID_TEMPLATE *)psStats, ModeQueue)) { return false; } @@ -6518,7 +6518,7 @@ static void intStatsRMBPressed(UDWORD id) if (!StructureIsManufacturingPending(psStructure)) { - structSetManufacture(psStructure, psNext); + structSetManufacture(psStructure, psNext, ModeQueue); } //need to check if this was the template that was mid-production @@ -6530,7 +6530,7 @@ static void intStatsRMBPressed(UDWORD id) if (StructureIsOnHoldPending(psStructure)) { - releaseProduction(psStructure); + releaseProduction(psStructure, ModeQueue); } // Reset the button on the object form @@ -6617,12 +6617,12 @@ static void intObjStatRMBPressed(UDWORD id) //if not curently on hold, set it if (!StructureIsOnHoldPending(psStructure)) { - holdProduction(psStructure); + holdProduction(psStructure, ModeQueue); } else { //cancel if have RMB-clicked twice - cancelProduction(psStructure); + cancelProduction(psStructure, ModeQueue); //play audio to indicate cancelled audio_PlayTrack(ID_SOUND_WINDOWCLOSE); } @@ -6636,12 +6636,12 @@ static void intObjStatRMBPressed(UDWORD id) //if not curently on hold, set it if (((RESEARCH_FACILITY *)psStructure->pFunctionality)->timeStartHold == 0) { - holdResearch(psStructure); + holdResearch(psStructure, ModeQueue); } else { //cancel if have RMB-clicked twice - cancelResearch(psStructure); + cancelResearch(psStructure, ModeQueue); //play audio to indicate cancelled audio_PlayTrack(ID_SOUND_WINDOWCLOSE); } diff --git a/src/mission.c b/src/mission.c index 3b1a884ac..3a564f9fe 100644 --- a/src/mission.c +++ b/src/mission.c @@ -949,11 +949,11 @@ void saveMissionLimboData(void) { if (StructIsFactory(psStruct)) { - holdProduction(psStruct); + holdProduction(psStruct, ModeQueue); } else if (psStruct->pStructureType->type == REF_RESEARCH) { - holdResearch(psStruct); + holdResearch(psStruct, ModeQueue); } } } diff --git a/src/multiplay.c b/src/multiplay.c index 4916095f8..193132d87 100644 --- a/src/multiplay.c +++ b/src/multiplay.c @@ -151,7 +151,7 @@ BOOL multiplayerWinSequence(BOOL firstCall) { if (((FACTORY *)psStruct->pFunctionality)->psSubject)//check if active { - cancelProduction(psStruct); + cancelProduction(psStruct, ModeQueue); } } } @@ -1012,9 +1012,7 @@ BOOL recvResearchStatus(NETQUEUE queue) if (psResFacilty->psSubject) { - turnOffMultiMsg(true); - cancelResearch(psBuilding); - turnOffMultiMsg(false); + cancelResearch(psBuilding, ModeImmediate); } // Set the subject up @@ -1077,9 +1075,7 @@ BOOL recvResearchStatus(NETQUEUE queue) // Stop the facility doing any research if (psBuilding) { - turnOffMultiMsg(true); - cancelResearch(psBuilding); - turnOffMultiMsg(false); + cancelResearch(psBuilding, ModeImmediate); } } diff --git a/src/multistruct.c b/src/multistruct.c index cbd88dad3..67aaa69a6 100644 --- a/src/multistruct.c +++ b/src/multistruct.c @@ -487,19 +487,17 @@ void recvStructureInfo(NETQUEUE queue) syncDebugStructure(psStruct, '<'); - turnOffMultiMsg(true); switch (structureInfo) { - case STRUCTUREINFO_MANUFACTURE: structSetManufacture(psStruct, psTempl); break; - case STRUCTUREINFO_CANCELPRODUCTION: cancelProduction(psStruct); break; - case STRUCTUREINFO_HOLDPRODUCTION: holdProduction(psStruct); break; - case STRUCTUREINFO_RELEASEPRODUCTION: releaseProduction(psStruct); break; - case STRUCTUREINFO_HOLDRESEARCH: holdResearch(psStruct); break; - case STRUCTUREINFO_RELEASERESEARCH: releaseResearch(psStruct); break; + case STRUCTUREINFO_MANUFACTURE: structSetManufacture(psStruct, psTempl, ModeImmediate); break; + case STRUCTUREINFO_CANCELPRODUCTION: cancelProduction(psStruct, ModeImmediate); break; + case STRUCTUREINFO_HOLDPRODUCTION: holdProduction(psStruct, ModeImmediate); break; + case STRUCTUREINFO_RELEASEPRODUCTION: releaseProduction(psStruct, ModeImmediate); break; + case STRUCTUREINFO_HOLDRESEARCH: holdResearch(psStruct, ModeImmediate); break; + case STRUCTUREINFO_RELEASERESEARCH: releaseResearch(psStruct, ModeImmediate); break; default: debug(LOG_ERROR, "Invalid structureInfo %d", structureInfo); } - turnOffMultiMsg(false); syncDebugStructure(psStruct, '>'); diff --git a/src/research.c b/src/research.c index 328a37918..1616d1ef9 100644 --- a/src/research.c +++ b/src/research.c @@ -1867,14 +1867,14 @@ void ResearchRelease(void) } /*puts research facility on hold*/ -void holdResearch(STRUCTURE *psBuilding) +void holdResearch(STRUCTURE *psBuilding, QUEUE_MODE mode) { RESEARCH_FACILITY *psResFac; ASSERT( psBuilding->pStructureType->type == REF_RESEARCH, "holdResearch: structure not a research facility" ); - if (bMultiMessages) + if (mode == ModeQueue) { sendStructureInfo(psBuilding, STRUCTUREINFO_HOLDRESEARCH, NULL); return; @@ -1896,14 +1896,14 @@ void holdResearch(STRUCTURE *psBuilding) } /*release a research facility from hold*/ -void releaseResearch(STRUCTURE *psBuilding) +void releaseResearch(STRUCTURE *psBuilding, QUEUE_MODE mode) { RESEARCH_FACILITY *psResFac; ASSERT( psBuilding->pStructureType->type == REF_RESEARCH, "releaseResearch: structure not a research facility" ); - if (bMultiMessages) + if (mode == ModeQueue) { sendStructureInfo(psBuilding, STRUCTUREINFO_RELEASERESEARCH, NULL); return; @@ -1942,7 +1942,7 @@ void CancelAllResearch(UDWORD pl) ) { debug( LOG_NEVER, "canceling research for %p\n", psCurr ); - cancelResearch(psCurr); + cancelResearch(psCurr, ModeQueue); } } @@ -1951,7 +1951,7 @@ void CancelAllResearch(UDWORD pl) /* sets the status of the topic to cancelled and stores the current research points accquired */ -void cancelResearch(STRUCTURE *psBuilding) +void cancelResearch(STRUCTURE *psBuilding, QUEUE_MODE mode) { UDWORD topicInc; PLAYER_RESEARCH *pPlayerRes; @@ -1976,7 +1976,7 @@ void cancelResearch(STRUCTURE *psBuilding) if (psBuilding->pStructureType->type == REF_RESEARCH) { - if (bMultiMessages) + if (mode == ModeQueue) { // Tell others that we want to stop researching something. sendResearchStatus(NULL, topicInc, psBuilding->player, false); diff --git a/src/research.h b/src/research.h index bfc1a73b7..df7073475 100644 --- a/src/research.h +++ b/src/research.h @@ -120,7 +120,7 @@ extern RESEARCH * getResearch(const char *pName, BOOL resName); /* sets the status of the topic to cancelled and stores the current research points accquired */ -extern void cancelResearch(STRUCTURE *psBuilding); +extern void cancelResearch(STRUCTURE *psBuilding, QUEUE_MODE mode); /* For a given view data get the research this is related to */ extern RESEARCH * getResearchForMsg(struct _viewdata *pViewData); @@ -141,9 +141,9 @@ extern SDWORD mapIconToRID(UDWORD iconID); extern BOOL checkResearchStats(void); /*puts research facility on hold*/ -extern void holdResearch(STRUCTURE *psBuilding); +extern void holdResearch(STRUCTURE *psBuilding, QUEUE_MODE mode); /*release a research facility from hold*/ -extern void releaseResearch(STRUCTURE *psBuilding); +extern void releaseResearch(STRUCTURE *psBuilding, QUEUE_MODE mode); /*checks the stat to see if its of type wall or defence*/ extern BOOL wallDefenceStruct(STRUCTURE_STATS *psStats); diff --git a/src/scriptfuncs.c b/src/scriptfuncs.c index 7a6508ede..415b5e6ab 100644 --- a/src/scriptfuncs.c +++ b/src/scriptfuncs.c @@ -1468,7 +1468,7 @@ BOOL scrBuildDroid(void) { debug(LOG_ERROR, "A script is trying to build a different number (%d) than 1 droid.", productionRun); } - structSetManufacture(psFactory, psTemplate); + structSetManufacture(psFactory, psTemplate, ModeQueue); return true; } diff --git a/src/structure.c b/src/structure.c index bdfc385b2..0238ceb55 100644 --- a/src/structure.c +++ b/src/structure.c @@ -1311,7 +1311,7 @@ BOOL structureRepair(STRUCTURE *psStruct, DROID *psDroid, int buildPoints) } /* Set the type of droid for a factory to build */ -BOOL structSetManufacture(STRUCTURE *psStruct, DROID_TEMPLATE *psTempl) +BOOL structSetManufacture(STRUCTURE *psStruct, DROID_TEMPLATE *psTempl, QUEUE_MODE mode) { FACTORY *psFact; @@ -1325,7 +1325,7 @@ BOOL structSetManufacture(STRUCTURE *psStruct, DROID_TEMPLATE *psTempl) psFact = &psStruct->pFunctionality->factory; - if (bMultiMessages) + if (mode == ModeQueue) { sendStructureInfo(psStruct, STRUCTUREINFO_MANUFACTURE, psTempl); psStruct->pFunctionality->factory.psSubjectPending = (BASE_STATS *)psTempl; @@ -1927,9 +1927,7 @@ STRUCTURE* buildStructureDir(STRUCTURE_STATS *pStructureType, UDWORD x, UDWORD y ++psBuilding->pFunctionality->factory.capacity; bUpgraded = true; //put any production on hold - turnOffMultiMsg(true); - holdProduction(psBuilding); - turnOffMultiMsg(false); + holdProduction(psBuilding, ModeImmediate); //quick check not trying to add too much ASSERT_OR_RETURN(NULL, psBuilding->pFunctionality->factory.productionOutput + @@ -2000,9 +1998,7 @@ STRUCTURE* buildStructureDir(STRUCTURE_STATS *pStructureType, UDWORD x, UDWORD y if (psBuilding->pFunctionality->researchFacility.psSubject) { //cancel the topic - turnOffMultiMsg(true); - holdResearch(psBuilding); - turnOffMultiMsg(false); + holdResearch(psBuilding, ModeImmediate); } //need to change which IMD is used for player 0 @@ -3551,9 +3547,8 @@ static void aiUpdateStructure(STRUCTURE *psStructure, bool isMission) psFactory->psSubject = NULL; // If quantity not 0 then kick of another manufacture. - turnOffMultiMsg(true); // Do instantly, since quantity is synchronised. - structSetManufacture(psStructure, (DROID_TEMPLATE *)pSubject); - turnOffMultiMsg(false); + // Do instantly, since quantity is synchronised. + structSetManufacture(psStructure, (DROID_TEMPLATE *)pSubject, ModeImmediate); //script callback, must be called after factory was flagged as idle if (bDroidPlaced) @@ -4938,7 +4933,7 @@ BOOL removeStruct(STRUCTURE *psDel, BOOL bDestroy) if (psDel->pFunctionality->researchFacility.psSubject) { //cancel the topic - cancelResearch(psDel); + cancelResearch(psDel, ModeImmediate); } } @@ -4954,7 +4949,7 @@ BOOL removeStruct(STRUCTURE *psDel, BOOL bDestroy) psFactory = &psDel->pFunctionality->factory; //need to initialise the production run as well - cancelProduction(psDel); + cancelProduction(psDel, ModeImmediate); psAssemblyPoint = psFactory->psAssemblyPoint; } @@ -5957,18 +5952,14 @@ void buildingComplete(STRUCTURE *psBuilding) break; case REF_RESEARCH: intCheckResearchButton(); - //this deals with researc facilities that are upgraded whilst mid-research - turnOffMultiMsg(true); - releaseResearch(psBuilding); - turnOffMultiMsg(false); + //this deals with research facilities that are upgraded whilst mid-research + releaseResearch(psBuilding, ModeImmediate); break; case REF_FACTORY: case REF_CYBORG_FACTORY: case REF_VTOL_FACTORY: //this deals with factories that are upgraded whilst mid-production - turnOffMultiMsg(true); - releaseProduction(psBuilding); - turnOffMultiMsg(false); + releaseProduction(psBuilding, ModeImmediate); break; case REF_SAT_UPLINK: revealAll(psBuilding->player); @@ -6868,7 +6859,7 @@ STRUCTURE *findDeliveryFactory(FLAG_POSITION *psDelPoint) /*cancels the production run for the factory and returns any power that was accrued but not used*/ -void cancelProduction(STRUCTURE *psBuilding) +void cancelProduction(STRUCTURE *psBuilding, QUEUE_MODE mode) { FACTORY *psFactory; @@ -6876,15 +6867,8 @@ void cancelProduction(STRUCTURE *psBuilding) psFactory = &psBuilding->pFunctionality->factory; - if (bMultiMessages) + if (mode == ModeQueue) { - if (psBuilding->player == productionPlayer) - { - //clear the production run for this factory - memset(asProductionRun[psFactory->psAssemblyPoint->factoryType][psFactory->psAssemblyPoint->factoryInc], 0, sizeof(PRODUCTION_RUN) * MAX_PROD_RUN); - psFactory->productionLoops = 0; - } - sendStructureInfo(psBuilding, STRUCTUREINFO_CANCELPRODUCTION, NULL); psFactory->psSubjectPending = NULL; @@ -6893,6 +6877,10 @@ void cancelProduction(STRUCTURE *psBuilding) if (psBuilding->player == productionPlayer) { + //clear the production run for this factory + memset(asProductionRun[psFactory->psAssemblyPoint->factoryType][psFactory->psAssemblyPoint->factoryInc], 0, sizeof(PRODUCTION_RUN) * MAX_PROD_RUN); + psFactory->productionLoops = 0; + //tell the interface intManufactureFinished(psBuilding); } @@ -6919,17 +6907,12 @@ void cancelProduction(STRUCTURE *psBuilding) //clear the factory's subject psFactory->psSubject = NULL; - if (psBuilding->player == productionPlayer && !bMultiPlayer) - { - //tell the interface - intManufactureFinished(psBuilding); - } } } /*set a factory's production run to hold*/ -void holdProduction(STRUCTURE *psBuilding) +void holdProduction(STRUCTURE *psBuilding, QUEUE_MODE mode) { FACTORY *psFactory; @@ -6937,7 +6920,7 @@ void holdProduction(STRUCTURE *psBuilding) psFactory = &psBuilding->pFunctionality->factory; - if (bMultiMessages) + if (mode == ModeQueue) { sendStructureInfo(psBuilding, STRUCTUREINFO_HOLDPRODUCTION, NULL); @@ -6945,7 +6928,7 @@ void holdProduction(STRUCTURE *psBuilding) { psFactory->psSubjectPending = psFactory->psSubject; } - if (psFactory->psSubjectPending != NULL) + else { psFactory->statusPending = FACTORY_HOLD_PENDING; } @@ -6968,7 +6951,7 @@ void holdProduction(STRUCTURE *psBuilding) } /*release a factory's production run from hold*/ -void releaseProduction(STRUCTURE *psBuilding) +void releaseProduction(STRUCTURE *psBuilding, QUEUE_MODE mode) { FACTORY *psFactory = &psBuilding->pFunctionality->factory; @@ -6976,7 +6959,7 @@ void releaseProduction(STRUCTURE *psBuilding) psFactory = &psBuilding->pFunctionality->factory; - if (bMultiMessages) + if (mode == ModeQueue) { sendStructureInfo(psBuilding, STRUCTUREINFO_RELEASEPRODUCTION, NULL); @@ -7010,12 +6993,12 @@ void doNextProduction(STRUCTURE *psStructure, DROID_TEMPLATE *current) if (psNextTemplate != NULL) { - structSetManufacture(psStructure, psNextTemplate); + structSetManufacture(psStructure, psNextTemplate, ModeQueue); } else { //nothing more to manufacture - cancelProduction(psStructure); + cancelProduction(psStructure, ModeQueue); } } diff --git a/src/structure.h b/src/structure.h index 8ce32700a..d35ef0452 100644 --- a/src/structure.h +++ b/src/structure.h @@ -123,7 +123,7 @@ extern void structureBuild(STRUCTURE *psStructure, DROID *psDroid, int buildPoin extern void structureDemolish(STRUCTURE *psStructure, DROID *psDroid, int buildPoints); extern BOOL structureRepair(STRUCTURE *psStruct, DROID *psDroid, int buildPoints); /* Set the type of droid for a factory to build */ -extern BOOL structSetManufacture(STRUCTURE *psStruct, DROID_TEMPLATE *psTempl); +extern BOOL structSetManufacture(STRUCTURE *psStruct, DROID_TEMPLATE *psTempl, QUEUE_MODE mode); //temp test function for creating structures at the start of the game extern void createTestStructures(void); @@ -326,13 +326,13 @@ extern void factoryLoopAdjust(STRUCTURE *psStruct, BOOL add); /*cancels the production run for the factory and returns any power that was accrued but not used*/ -extern void cancelProduction(STRUCTURE *psBuilding); +extern void cancelProduction(STRUCTURE *psBuilding, QUEUE_MODE mode); /*set a factory's production run to hold*/ -extern void holdProduction(STRUCTURE *psBuilding); +extern void holdProduction(STRUCTURE *psBuilding, QUEUE_MODE mode); /*release a factory's production run from hold*/ -extern void releaseProduction(STRUCTURE *psBuilding); +extern void releaseProduction(STRUCTURE *psBuilding, QUEUE_MODE mode); /// Does the next item in the production list. void doNextProduction(STRUCTURE *psStructure, DROID_TEMPLATE *current);