Introduce ModeQueue and ModeImmediate as an alternative to playing with bMultiMessages.

Makes campaign queue some messages, and fixes cancelling production queues in campaign.
master
Cyp 2010-10-22 18:13:04 +02:00
parent 714b465743
commit fcdba754c4
12 changed files with 73 additions and 93 deletions

View File

@ -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

View File

@ -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.
{

View File

@ -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
{

View File

@ -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);
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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, '>');

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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);