/**
**  Game main loop.
**
**  Unit actions.
**  Missile actions.
**  Players (AI).
**  Cyclic events (color cycle,...)
**  Display update.
**  Input/Network/Sound.
*/
void GameMainLoop()
{
	const EventCallback *old_callbacks;

	InitGameCallbacks();

	old_callbacks = GetCallbacks();
	SetCallbacks(&GameCallbacks);

	SetVideoSync();
	GameCursor = UI.Point.Cursor;
	GameRunning = true;

	CParticleManager::init();

#ifdef REALVIDEO
	RealVideoSyncSpeed = VideoSyncSpeed;
#endif

	CclCommand("if (GameStarting ~= nil) then GameStarting() end");

	MultiPlayerReplayEachCycle();

	SingleGameLoop();

	//
	// Game over
	//
	if (GameResult == GameExit) {
		Exit(0);
		return;
	}

#ifdef REALVIDEO
	if (FastForwardCycle > GameCycle) {
		VideoSyncSpeed = RealVideoSyncSpeed;
	}
#endif
	NetworkQuitGame();
	EndReplayLog();

	GameCycle = 0;//????
	CParticleManager::exit();
	FlagRevealMap = 0;
	ReplayRevealMap = 0;
	GamePaused = false;
	GodMode = false;

	SetCallbacks(old_callbacks);
}
/**
**  Game main loop.
**
**  Unit actions.
**  Missile actions.
**  Players (AI).
**  Cyclic events (color cycle,...)
**  Display update.
**  Input/Network/Sound.
*/
void GameMainLoop(void)
{
	int player;
	const EventCallback *old_callbacks;

	InitGameCallbacks();

	old_callbacks = GetCallbacks();
	SetCallbacks(&GameCallbacks);

	SetVideoSync();
	GameCursor = UI.Point.Cursor;
	GameRunning = true;

	CParticleManager::init();

	MultiPlayerReplayEachCycle();

	CclCommand("GameStarting()");

	std::ofstream output;
	std::wstring templ;
	firstClock = std::clock();
        templateClock = 0;
	int messageNumber = 1;
	std::ofstream outputEventsPerSec;
	std::ofstream outputNT;
	outputEventsPerSec.open("/tmp/boswarseventspersec.csv",std::ios::out);
   	outputNT.open("/tmp/boswarsclocksperevents.csv",std::ios::out);

	output.open("/tmp/beepbeep.fifo",std::ios::out);

	templ = templ = L"<message>\n"
				L"  <units>\n"
				    L"{% for unit in units.tabunits %}"
				    L"  <unit>\n"
				    L"    <id>{$unit.id}</id>\n"
				    L"    <type>{$unit.type}</type>\n"
				    L"    <isbuilding>{$unit.isbuilding}</isbuilding>\n"
				    L"    <player>{$unit.player}</player>\n"
				    L"    <order>\n"
				    L"      <action>{$unit.action}</action>\n"
				    L"      <goal>{$unit.goal}</goal>\n"
				    L"    </order>\n"
				    L"    <neworder>\n"
				    L"       <action>{$unit.neworder}</action>\n"
				    L"       <goal>{$unit.newgoal}</goal>\n"
				    L"    </neworder>\n"
				    L"  </unit>\n"
				    L"{% endfor %}"
             		   	L"  </units>\n"
				L"<overhead>{$overhead}</overhead>\n"
            		L"</message>\n"; 

	

	while (GameRunning) {

		// Can't find a better place.
		SaveGameLoading = false;
		//
		// Game logic part
		//
		if (!GamePaused && NetworkInSync && !SkipGameCycle) {
			SinglePlayerReplayEachCycle();
			++GameCycle;
			MultiPlayerReplayEachCycle();
			NetworkCommands();  // Get network commands
			UnitActions();      // handle units
			MissileActions();   // handle missiles
			PlayersEachCycle(); // handle players
			UpdateTimer();      // update game timer

			//
			// Work todo each second.
			// Split into different frames, to reduce cpu time.
			// Increment mana of magic units.
			// Update mini-map.
			// Update map fog of war.
			// Call AI.
			// Check game goals.
			// Check rescue of units.
			//
			switch (GameCycle % CYCLES_PER_SECOND) {
				case 0: // At cycle 0, start all ai players...
					if (GameCycle == 0) {
						for (player = 0; player < NumPlayers; ++player) {
							PlayersEachSecond(player);
						}
					}
					break;
				case 1:
					break;
				case 2:
					break;
				case 3: // minimap update
					UI.Minimap.Update();
					break;
				case 4:
					break;
				case 5:
					break;
				case 6: // overtaking units
					RescueUnits();
					break;
				default:
					// FIXME: assume that NumPlayers < (CYCLES_PER_SECOND - 7)
					player = (GameCycle % CYCLES_PER_SECOND) - 7;
					Assert(player >= 0);
					if (player < NumPlayers) {
						PlayersEachSecond(player);
					}
			}

			////////////GET INFORMATION FOR MONITORING!!!////////////////////
			
						

			if(NumUnits > 0)
			{
				std::clock_t littleClock = std::clock();
	
				cpptempl::data_list theUnits;
		    
		    		std::stringstream ss;

				for(int i = 0; i < NumUnits; i++)
				{
					cpptempl::data_map uni;

					/////////ID/////////
					ss.str("");
					ss << Units[i]->Slot;
					std::string theID = ss.str();
					std::wstring wTheID;
					wTheID.assign(theID.begin(),theID.end());
					uni[L"id"] = cpptempl::make_data(wTheID);

					//////UNITTYPE//////
					ss.str("");
					ss << Units[i]->Type->Name;
					std::string theType = ss.str();
					std::wstring wTheType;
					wTheType.assign(theType.begin(),theType.end());
					uni[L"type"] = cpptempl::make_data(wTheType);

					//////ISBUILDING//////
					ss.str("");
					if (Units[i]->Type->Building == 1)
						ss << "true";
					else
						ss << "false";
					std::string theIsBuilding = ss.str();
					std::wstring wTheIsBuilding;
					wTheIsBuilding.assign(theIsBuilding.begin(),theIsBuilding.end());
					uni[L"isbuilding"] = cpptempl::make_data(wTheIsBuilding);

					//////PLAYER//////
					ss.str("");
					ss << Units[i]->Player;
					std::string thePlayer = ss.str();
					std::wstring wThePlayer;
					wThePlayer.assign(thePlayer.begin(),thePlayer.end());
					uni[L"player"] = cpptempl::make_data(wThePlayer);

					//////UnitAction//////
					ss.str("");
					switch(Units[i]->Orders[0]->Action)
					{
					  	case UnitActionNone: ss << "UnitActionNone"; break;
						case UnitActionStill: ss << "UnitActionStill"; break;  
						case UnitActionStandGround: ss << "UnitActionStandGround"; break;
						case UnitActionFollow: ss << "UnitActionFollow"; break;    
						case UnitActionMove: ss << "UnitActionMove"; break;      
						case UnitActionAttack: ss << "UnitActionAttack"; break;   
						case UnitActionAttackGround: ss << "UnitActionAttackGround"; break;
						case UnitActionDie: ss << "UnitActionDie"; break;     

						case UnitActionSpellCast: ss << "UnitActionSpellCast"; break; 

						case UnitActionTrain: ss << "UnitActionTrain"; break;  
						case UnitActionBuilt: ss << "UnitActionBuilt"; break;   
						case UnitActionBoard: ss << "UnitActionBoard"; break;    
						case UnitActionUnload: ss << "UnitActionUnload"; break; 
						case UnitActionPatrol: ss << "UnitActionPatrol"; break; 
						case UnitActionBuild: ss << "UnitActionBuild"; break;

						case UnitActionRepair: ss << "UnitActionRepair"; break; 
						case UnitActionResource: ss << "UnitActionResource"; break;
						default: ss << "None";  
					}

					std::string theAction = ss.str();
					std::wstring wTheAction;
					wTheAction.assign(theAction.begin(),theAction.end());
					uni[L"action"] = cpptempl::make_data(wTheAction);

					//////UnitGoal//////
					ss.str("");
					if(Units[i]->Orders[0]->Goal != NULL)
						ss << Units[i]->Orders[0]->Goal->Slot;
					else
						ss << "None";
					std::string theGoal = ss.str();
					std::wstring wTheGoal;
					wTheGoal.assign(theGoal.begin(),theGoal.end());
					uni[L"goal"] = cpptempl::make_data(wTheGoal);

					///////NEW ORDER/////////
					ss.str("");
					switch(Units[i]->NewOrder.Action)
					{
					  	case UnitActionNone: ss << "UnitActionNone"; break;
						case UnitActionStill: ss << "UnitActionStill"; break;  
						case UnitActionStandGround: ss << "UnitActionStandGround"; break;
						case UnitActionFollow: ss << "UnitActionFollow"; break;    
						case UnitActionMove: ss << "UnitActionMove"; break;      
						case UnitActionAttack: ss << "UnitActionAttack"; break;   
						case UnitActionAttackGround: ss << "UnitActionAttackGround"; break;
						case UnitActionDie: ss << "UnitActionDie"; break;     

						case UnitActionSpellCast: ss << "UnitActionSpellCast"; break; 

						case UnitActionTrain: ss << "UnitActionTrain"; break;  
						case UnitActionBuilt: ss << "UnitActionBuilt"; break;   
						case UnitActionBoard: ss << "UnitActionBoard"; break;    
						case UnitActionUnload: ss << "UnitActionUnload"; break; 
						case UnitActionPatrol: ss << "UnitActionPatrol"; break; 
						case UnitActionBuild: ss << "UnitActionBuild"; break;

						case UnitActionRepair: ss << "UnitActionRepair"; break; 
						case UnitActionResource: ss << "UnitActionResource"; break;
						default: ss << "None";  
					}

					std::string theNewOrder = ss.str();
					std::wstring wTheNewOrder;
					wTheNewOrder.assign(theNewOrder.begin(),theNewOrder.end());
					uni[L"neworder"] = cpptempl::make_data(wTheNewOrder);

					//////NEW GOAL//////
					ss.str("");
					if(Units[i]->NewOrder.Goal != NULL)
						ss << Units[i]->NewOrder.Goal->Slot;
					else
						ss << "None";
					std::string theNewGoal = ss.str();
					std::wstring wTheNewGoal;
					wTheNewGoal.assign(theNewGoal.begin(),theNewGoal.end());
					uni[L"newgoal"] = cpptempl::make_data(wTheNewGoal);
			
					theUnits.push_back((cpptempl::make_data(uni)));
				}
				

				cpptempl::data_map lesUnits;
		    		lesUnits[L"tabunits"] = cpptempl::make_data(theUnits);

				// Now set this in the data map
				cpptempl::data_map data;
				data[L"units"] = cpptempl::make_data(lesUnits);

				//////////////////TIMESTAMP/////////////////////////
				std::clock_t t = std::clock() - firstClock;
				double timeStamp = ((double)t/(double)CLOCKS_PER_SEC);
				ss.str("");
				ss << std::setprecision(8) << timeStamp;
				std::string sTimeStamp = ss.str();
				std::string gnuPlotStringT = ss.str();
				std::wstring wTimeStamp;
				wTimeStamp.assign(sTimeStamp.begin(),sTimeStamp.end());
				data[L"timestamp"] = cpptempl::make_data(wTimeStamp);

				///OVERHEAD/////
				templateClock += std::clock()-littleClock;
				long double overhead = (long double)templateClock / ((long double)std::clock()-(long double)firstClock)*(long double)100.0;
				ss.str("");
				ss << std::setprecision(10) << overhead;
				std::string sOverhead = ss.str();
				std::wstring wOverhead;
				wOverhead.assign(sOverhead.begin(),sOverhead.end());
				data[L"overhead"] = cpptempl::make_data(wOverhead);
				std::cout << overhead << "% overhead\n";
				//std::cout << std::clock() << " clocl\n";

				/////////////////MESSAGENUMBER/////////////////////////<
			        ss.str("");
			        ss << messageNumber;
			        std::string gnuPlotStringN = ss.str();
			        std::string sMessageNumber = ss.str();
			        std::wstring wMessageNumber;
			        wMessageNumber.assign(sMessageNumber.begin(),sMessageNumber.end());
			        data[L"messagenumber"] = cpptempl::make_data(wMessageNumber);

				std::wstring result = cpptempl::parse(templ, data);
				
				ss.str("");
				
				double templateTime = ((double)templateClock/(double)CLOCKS_PER_SEC)*(double)1000;
				ss << std::setprecision(8) << templateTime;
				std::string templTime = ss.str();				
				
				double totalT = ((std::clock()-firstClock)/(double)CLOCKS_PER_SEC);
				std::cout << totalT << "totaltime\n";
				std::cout << CYCLES_PER_SECOND << "cycles\n";
				std::string s;
		    		s.assign(result.begin(), result.end());
				
				if (messageNumber == 1)
				{
					std::ofstream traceoutput;
					traceoutput.open("/tmp/traceout.xml",std::ios::out);
					traceoutput << s;
					traceoutput.close();
				}

				messageNumber++;

				/////STATS/////
								

				output << s;
		
				std::string out = gnuPlotStringN + "," + gnuPlotStringT + "\n";
				outputEventsPerSec << out;
		
				//OutputNT
				//std::string theT;
				out = "";
				//ss.str("");
				//ss << templTime;
				//theT = ss.str();
				out = templTime + "," + gnuPlotStringN + "\n";
				outputNT << out;
				
			}
			/////////////////////////////////////////////////////////////////
		}

		TriggersEachCycle();      // handle triggers
		UpdateMessages();         // update messages
		ParticleManager.update(); // handle particles

		CheckMusicFinished();     // Check for next song

		//
		// Map scrolling
		//
		DoScrollArea(MouseScrollState | KeyScrollState, (KeyModifiers & ModifierControl) != 0);

		if (FastForwardCycle <= GameCycle || GameCycle <= 10 || !(GameCycle & 0x3f)) {
			//FIXME: this might be better placed somewhere at front of the
			// program, as we now still have a game on the background and
			// need to go through the game-menu or supply a map file
			UpdateDisplay();

			//
			// If double-buffered mode, we will display the contains of
			// VideoMemory. If direct mode this does nothing. In X11 it does
			// XFlush
			//
			RealizeVideoMemory();
		}

		if (FastForwardCycle <= GameCycle || !(GameCycle & 0x3f)) {
			WaitEventsOneFrame();
		}
		if (!NetworkInSync) {
			NetworkRecover(); // recover network
		}

		
	}

	output.close();
	outputNT.close();
    	outputEventsPerSec.close();
	//
	// Game over
	//
	NetworkQuit();
	EndReplayLog();

	CParticleManager::exit();

	FlagRevealMap = 0;
	ReplayRevealMap = 0;
	GamePaused = false;
	GodMode = false;

	SetCallbacks(old_callbacks);
}
static void GameLogicLoop()
{
	// Can't find a better place.
	// FIXME: We need find better place!
	SaveGameLoading = false;

	//
	// Game logic part
	//
	if (!GamePaused && NetworkInSync && !SkipGameCycle) {
		SinglePlayerReplayEachCycle();
		++GameCycle;
		MultiPlayerReplayEachCycle();
		NetworkCommands(); // Get network commands
		TriggersEachCycle();// handle triggers
		UnitActions();      // handle units
		MissileActions();   // handle missiles
		PlayersEachCycle(); // handle players
		UpdateTimer();      // update game timer


		//
		// Work todo each second.
		// Split into different frames, to reduce cpu time.
		// Increment mana of magic units.
		// Update mini-map.
		// Update map fog of war.
		// Call AI.
		// Check game goals.
		// Check rescue of units.
		//
		switch (GameCycle % CYCLES_PER_SECOND) {
			case 0: // At cycle 0, start all ai players...
				if (GameCycle == 0) {
					for (int player = 0; player < NumPlayers; ++player) {
						PlayersEachSecond(player);
					}
				}
				break;
			case 1:
				break;
			case 2:
				break;
			case 3: // minimap update
				UI.Minimap.UpdateCache = true;
				break;
			case 4:
				break;
			case 5: // forest grow
				Map.RegenerateForest();
				break;
			case 6: // overtaking units
				RescueUnits();
				break;
			default: {
				// FIXME: assume that NumPlayers < (CYCLES_PER_SECOND - 7)
				int player = (GameCycle % CYCLES_PER_SECOND) - 7;
				Assert(player >= 0);
				if (player < NumPlayers) {
					PlayersEachSecond(player);
				}
			}
		}
	}

	UpdateMessages();     // update messages
	ParticleManager.update(); // handle particles
	CheckMusicFinished(); // Check for next song

	if (FastForwardCycle <= GameCycle || !(GameCycle & 0x3f)) {
		WaitEventsOneFrame();
	}

	if (!NetworkInSync) {
		NetworkRecover(); // recover network
	}
}
Exemple #4
0
/**
**  Game main loop.
**
**  Unit actions.
**  Missile actions.
**  Players (AI).
**  Cyclic events (color cycle,...)
**  Display update.
**  Input/Network/Sound.
*/
void GameMainLoop()
{
	const EventCallback *old_callbacks;

	InitGameCallbacks();

	old_callbacks = GetCallbacks();
	SetCallbacks(&GameCallbacks);

	SetVideoSync();
	GameCursor = UI.Point.Cursor;
	GameRunning = true;

	CParticleManager::init();

#ifdef REALVIDEO
	RealVideoSyncSpeed = VideoSyncSpeed;
#endif

	CclCommand("if (GameStarting ~= nil) then GameStarting() end");

	MultiPlayerReplayEachCycle();
	
	//Wyrmgus start
	//if the person player has no faction, bring up the faction choice interface
	if (!GrandStrategy && ThisPlayer && ThisPlayer->Faction == -1) {
		char buf[256];
		snprintf(buf, sizeof(buf), "if (ChooseFaction ~= nil) then ChooseFaction(\"%s\", \"%s\") end", ThisPlayer->Race != -1 ? PlayerRaces.Name[ThisPlayer->Race].c_str() : "", "");
		CclCommand(buf);
	}
	
	if (!IsNetworkGame() && ThisPlayer && CurrentCustomHero != NULL) {
		Vec2i resPos;
		FindNearestDrop(*CurrentCustomHero->Type, ThisPlayer->StartPos, resPos, LookingW);
		CUnit *custom_hero = MakeUnitAndPlace(resPos, *CurrentCustomHero->Type, ThisPlayer);
		custom_hero->SetCharacter(CurrentCustomHero->GetFullName(), true);	
	}
	//Wyrmgus end

	SingleGameLoop();

	//
	// Game over
	//
	if (GameResult == GameExit) {
		Exit(0);
		return;
	}

#ifdef REALVIDEO
	if (FastForwardCycle > GameCycle) {
		VideoSyncSpeed = RealVideoSyncSpeed;
	}
#endif
	NetworkQuitGame();
	EndReplayLog();

	GameCycle = 0;//????
	//Wyrmgus start
	GameTimeOfDay = NoTimeOfDay;
	//Wyrmgus end
	CParticleManager::exit();
	FlagRevealMap = 0;
	ReplayRevealMap = 0;
	GamePaused = false;
	GodMode = false;

	SetCallbacks(old_callbacks);
}
Exemple #5
0
static void GameLogicLoop()
{
	// Can't find a better place.
	// FIXME: We need find better place!
	SaveGameLoading = false;

	//
	// Game logic part
	//
	if (!GamePaused && NetworkInSync && !SkipGameCycle) {
		SinglePlayerReplayEachCycle();
		++GameCycle;
		MultiPlayerReplayEachCycle();
		NetworkCommands(); // Get network commands
		TriggersEachCycle();// handle triggers
		UnitActions();      // handle units
		MissileActions();   // handle missiles
		PlayersEachCycle(); // handle players
		UpdateTimer();      // update game timer


		//
		// Work todo each second.
		// Split into different frames, to reduce cpu time.
		// Increment mana of magic units.
		// Update mini-map.
		// Update map fog of war.
		// Call AI.
		// Check game goals.
		// Check rescue of units.
		//
		switch (GameCycle % CYCLES_PER_SECOND) {
			case 0: // At cycle 0, start all ai players...
				if (GameCycle == 0) {
					for (int player = 0; player < NumPlayers; ++player) {
						PlayersEachSecond(player);
					}
				}
				break;
			case 1:
				break;
			case 2:
				break;
			case 3: // minimap update
				UI.Minimap.UpdateCache = true;
				break;
			case 4:
				break;
			case 5: // forest grow
				Map.RegenerateForest();
				break;
			case 6: // overtaking units
				RescueUnits();
				break;
			default: {
				// FIXME: assume that NumPlayers < (CYCLES_PER_SECOND - 7)
				int player = (GameCycle % CYCLES_PER_SECOND) - 7;
				Assert(player >= 0);
				if (player < NumPlayers) {
					PlayersEachSecond(player);
				}
			}
		}
		
		//Wyrmgus start
		if (GameCycle > 0 && GameCycle % (CYCLES_PER_SECOND * 10 * 3) == 0) { // every 10 seconds of gameplay = 1 hour for time of day calculations, change time of day every three hours
			if (!GameSettings.Inside) { // only change the time of the day if outdoors
				GameTimeOfDay += 1;
				if (GameTimeOfDay == MaxTimesOfDay) {
					GameTimeOfDay = 1;
				}
			} else {
				// indoors it is always dark (maybe would be better to allow a special setting to have bright indoor places?
				GameTimeOfDay = NoTimeOfDay; // make indoors have no time of day setting until it is possible to make light sources change their surrounding "time of day"
			}
			//update the sight of all units
			for (CUnitManager::Iterator it = UnitManager.begin(); it != UnitManager.end(); ++it) {
				CUnit &unit = **it;
				if (!unit.Destroyed) {
					MapUnmarkUnitSight(unit);
					UpdateUnitSightRange(unit);
					MapMarkUnitSight(unit);
				}
			}
		}
		//Wyrmgus end
		
		//Wyrmgus start
//		if (Preference.AutosaveMinutes != 0 && !IsNetworkGame() && GameCycle > 0 && (GameCycle % (CYCLES_PER_SECOND * 60 * Preference.AutosaveMinutes)) == 0) { // autosave every X minutes, if the option is enabled
		if (Preference.AutosaveMinutes != 0 && !IsNetworkGame() && !GrandStrategy && GameCycle > 0 && (GameCycle % (CYCLES_PER_SECOND * 60 * Preference.AutosaveMinutes)) == 0) { // autosave every X minutes, if the option is enabled
		//Wyrmgus end
			UI.StatusLine.Set(_("Autosave"));
			//Wyrmgus start
//			SaveGame("autosave.sav");
			CclCommand("if (RunSaveGame ~= nil) then RunSaveGame(\"autosave.sav\") end;");
			//Wyrmgus end
		}
	}

	UpdateMessages();     // update messages
	ParticleManager.update(); // handle particles
	CheckMusicFinished(); // Check for next song

	if (FastForwardCycle <= GameCycle || !(GameCycle & 0x3f)) {
		WaitEventsOneFrame();
	}

	if (!NetworkInSync) {
		NetworkRecover(); // recover network
	}
}
Exemple #6
0
/**
**  Game main loop.
**
**  Unit actions.
**  Missile actions.
**  Players (AI).
**  Cyclic events (color cycle,...)
**  Display update.
**  Input/Network/Sound.
*/
void GameMainLoop(void)
{
#ifdef DEBUG  // removes the setjmp warnings
	static bool showtip;
#else
	bool showtip;
#endif
	int player;
	int RealVideoSyncSpeed;
	const EventCallback *old_callbacks;

	InitGameCallbacks();

	old_callbacks = GetCallbacks();
	SetCallbacks(&GameCallbacks);

	SetVideoSync();
	GameCursor = UI.Point.Cursor;
	GameRunning = true;

	showtip = false;
	RealVideoSyncSpeed = VideoSyncSpeed;

	MultiPlayerReplayEachCycle();

	// StratagusAI MOD
	GamePaused = true;
	// Minimap.Update();
        
	while (GameRunning) {
		// StratagusAI MOD
		if ((GameCycle - socketInterface->lastPausedCycle) %
				socketInterface->cyclesPerTransition == 0) {
			socketInterface->handleInterface();
			if (socketInterface->warpSpeed)
				FastForwardCycle = GameCycle +
					socketInterface->cyclesPerTransition + 1;
		}

		// Can't find a better place.
		SaveGameLoading = 0;
		//
		// Game logic part
		//
		if (!GamePaused && NetworkInSync && !SkipGameCycle) {
			SinglePlayerReplayEachCycle();
			++GameCycle;
			MultiPlayerReplayEachCycle();
			NetworkCommands(); // Get network commands
			UnitActions();      // handle units
			MissileActions();   // handle missiles
			PlayersEachCycle(); // handle players
			UpdateTimer();      // update game timer

			//
			// Work todo each second.
			// Split into different frames, to reduce cpu time.
			// Increment mana of magic units.
			// Update mini-map.
			// Update map fog of war.
			// Call AI.
			// Check game goals.
			// Check rescue of units.
			//
			switch (GameCycle % CYCLES_PER_SECOND) {
				case 0: // At cycle 0, start all ai players...
					if (GameCycle == 0) {
						for (player = 0; player < NumPlayers; ++player) {
							PlayersEachSecond(player);
						}
					}
					break;
				case 1:
					break;
				case 2:
					break;
				case 3: // minimap update
					UI.Minimap.Update();
					break;
				case 4:
					break;
				case 5:
					break;
				case 6: // overtaking units
					RescueUnits();
					break;
				default:
					// FIXME: assume that NumPlayers < (CYCLES_PER_SECOND - 7)
					player = (GameCycle % CYCLES_PER_SECOND) - 7;
					Assert(player >= 0);
					if (player < NumPlayers) {
						PlayersEachSecond(player);
					}
			}
		}

		TriggersEachCycle();  // handle triggers
		UpdateMessages();     // update messages

		CheckMusicFinished(); // Check for next song

		//
		// Map scrolling
		//
		DoScrollArea(MouseScrollState | KeyScrollState, (KeyModifiers & ModifierControl) != 0);

		if (FastForwardCycle > GameCycle &&
				RealVideoSyncSpeed != VideoSyncSpeed) {
			RealVideoSyncSpeed = VideoSyncSpeed;
			VideoSyncSpeed = 3000;
		}

		// MOD
		if (socketInterface->cyclesPerVideoUpdate != -1 &&
				(GameCycle % socketInterface->cyclesPerVideoUpdate == 0 || GamePaused))
		{
			if (FastForwardCycle <= GameCycle || GameCycle <= 10 || !(GameCycle & 0x3f)) {
				//FIXME: this might be better placed somewhere at front of the
				// program, as we now still have a game on the background and
				// need to go through the game-menu or supply a map file
				UpdateDisplay();

				//
				// If double-buffered mode, we will display the contains of
				// VideoMemory. If direct mode this does nothing. In X11 it does
				// XFlush
				//
				RealizeVideoMemory();
			}
		}

		if (FastForwardCycle == GameCycle) {
			VideoSyncSpeed = RealVideoSyncSpeed;
		}
		if (FastForwardCycle <= GameCycle || !(GameCycle & 0x3f)) {
			WaitEventsOneFrame();
		}
		if (!NetworkInSync) {
			NetworkRecover(); // recover network
		}
	}

	//
	// Game over
	//
	if (FastForwardCycle > GameCycle) {
		VideoSyncSpeed = RealVideoSyncSpeed;
	}
	NetworkQuit();
	EndReplayLog();

	FlagRevealMap = 0;
	ReplayRevealMap = 0;
	GamePaused = false;
	GodMode = false;

	SetCallbacks(old_callbacks);
}
Exemple #7
0
/**
**  Game main loop.
**
**  Unit actions.
**  Missile actions.
**  Players (AI).
**  Cyclic events (color cycle,...)
**  Display update.
**  Input/Network/Sound.
*/
void GameMainLoop()
{
	const EventCallback *old_callbacks;

	InitGameCallbacks();

	old_callbacks = GetCallbacks();
	SetCallbacks(&GameCallbacks);

	SetVideoSync();
	GameCursor = UI.Point.Cursor;
	//Wyrmgus start
	GameEstablishing = false;
	//Wyrmgus end
	GameRunning = true;

	CParticleManager::init();

#ifdef REALVIDEO
	RealVideoSyncSpeed = VideoSyncSpeed;
#endif

	CclCommand("if (GameStarting ~= nil) then GameStarting() end");

	MultiPlayerReplayEachCycle();
	
	//Wyrmgus start
	if (GameCycle == 0) { // so that these don't trigger when loading a saved game
		if (CurrentCampaign != NULL) {
			for (int i = 0; i < NumPlayers; ++i) {
				if (Players[i].Type != PlayerNobody && Players[i].Race != 0 && Players[i].Faction != -1) {
					if (CurrentCampaign->StartDate.year) {
						CCivilization *civilization = PlayerRaces.Civilizations[Players[i].Race];
						CFaction *faction = PlayerRaces.Factions[Players[i].Race][Players[i].Faction];
						
						for (std::map<std::string, std::map<CDate, bool>>::iterator iterator = civilization->HistoricalUpgrades.begin(); iterator != civilization->HistoricalUpgrades.end(); ++iterator) {
							int upgrade_id = UpgradeIdByIdent(iterator->first);
							if (upgrade_id == -1) {
								fprintf(stderr, "Upgrade \"%s\" doesn't exist.\n", iterator->first.c_str());
								continue;
							}
							for (std::map<CDate, bool>::reverse_iterator second_iterator = iterator->second.rbegin(); second_iterator != iterator->second.rend(); ++second_iterator) {
								if (second_iterator->first.year == 0 || CurrentCampaign->StartDate >= second_iterator->first) {
									if (second_iterator->second && UpgradeIdentAllowed(Players[i], iterator->first.c_str()) != 'R') {
										UpgradeAcquire(Players[i], AllUpgrades[upgrade_id]);
									} else if (!second_iterator->second) {
										break;
									}
								}
							}
						}
						
						for (std::map<std::string, std::map<CDate, bool>>::iterator iterator = faction->HistoricalUpgrades.begin(); iterator != faction->HistoricalUpgrades.end(); ++iterator) {
							int upgrade_id = UpgradeIdByIdent(iterator->first);
							if (upgrade_id == -1) {
								fprintf(stderr, "Upgrade \"%s\" doesn't exist.\n", iterator->first.c_str());
								continue;
							}
							for (std::map<CDate, bool>::reverse_iterator second_iterator = iterator->second.rbegin(); second_iterator != iterator->second.rend(); ++second_iterator) {
								if (second_iterator->first.year == 0 || CurrentCampaign->StartDate >= second_iterator->first) {
									if (second_iterator->second && UpgradeIdentAllowed(Players[i], iterator->first.c_str()) != 'R') {
										UpgradeAcquire(Players[i], AllUpgrades[upgrade_id]);
									} else if (!second_iterator->second) {
										break;
									}
								}
							}
						}

						for (std::map<std::pair<int, CFaction *>, int>::iterator iterator = faction->HistoricalDiplomacyStates.begin(); iterator != faction->HistoricalDiplomacyStates.end(); ++iterator) { //set the appropriate historical diplomacy states to other factions
							if (iterator->second == 0 || CurrentCampaign->StartDate.year >= iterator->first.first) {
								CPlayer *diplomacy_state_player = GetFactionPlayer(iterator->first.second);
								if (diplomacy_state_player) {
									CommandDiplomacy(i, iterator->second, diplomacy_state_player->Index);
									CommandDiplomacy(diplomacy_state_player->Index, iterator->second, i);
									if (iterator->second == DiplomacyAllied) {
										CommandSharedVision(i, true, diplomacy_state_player->Index);
										CommandSharedVision(diplomacy_state_player->Index, true, i);
									}
								}
							}
						}

						for (std::map<std::pair<CDate, int>, int>::iterator iterator = faction->HistoricalResources.begin(); iterator != faction->HistoricalResources.end(); ++iterator) { //set the appropriate historical resource quantities
							if (iterator->second == 0 || CurrentCampaign->StartDate >= iterator->first.first) {
								Players[i].SetResource(iterator->first.second, iterator->second);
							}
						}
					}
				}
			}
	
			if (CurrentCampaign->StartEffects) {
				CurrentCampaign->StartEffects->pushPreamble();
				CurrentCampaign->StartEffects->run();
			}
		}
		
		//if the person player has no faction, bring up the faction choice interface
		if (!GrandStrategy && ThisPlayer && ThisPlayer->Faction == -1) {
			char buf[256];
			snprintf(buf, sizeof(buf), "if (ChooseFaction ~= nil) then ChooseFaction(\"%s\", \"%s\") end", ThisPlayer->Race != -1 ? PlayerRaces.Name[ThisPlayer->Race].c_str() : "", "");
			CclCommand(buf);
		}
		
		if (!IsNetworkGame() && ThisPlayer && CurrentCustomHero != NULL) {
			Vec2i resPos;
			FindNearestDrop(*CurrentCustomHero->Type, ThisPlayer->StartPos, resPos, LookingW, ThisPlayer->StartMapLayer);
			CUnit *custom_hero = MakeUnitAndPlace(resPos, *CurrentCustomHero->Type, ThisPlayer, ThisPlayer->StartMapLayer);
			custom_hero->SetCharacter(CurrentCustomHero->Ident, true);	
		}
		
		if (CurrentQuest != NULL && CurrentQuest->IntroductionDialogue != NULL) {
			CurrentQuest->IntroductionDialogue->Call(ThisPlayer->Index);
		}
	}
	//Wyrmgus end

	SingleGameLoop();

	//
	// Game over
	//
	if (GameResult == GameExit) {
		Exit(0);
		return;
	}

#ifdef REALVIDEO
	if (FastForwardCycle > GameCycle) {
		VideoSyncSpeed = RealVideoSyncSpeed;
	}
#endif
	NetworkQuitGame();
	EndReplayLog();

	GameCycle = 0;//????
	CParticleManager::exit();
	FlagRevealMap = 0;
	ReplayRevealMap = 0;
	GamePaused = false;
	GodMode = false;

	SetCallbacks(old_callbacks);
}
Exemple #8
0
static void GameLogicLoop()
{
	// Can't find a better place.
	// FIXME: We need find better place!
	SaveGameLoading = false;

#ifdef USE_OAML
	if (enableOAML && oaml) {
		// Time of day can change our main music loop, if the current playing track is set for this
		SetMusicCondition(OAML_CONDID_MAIN_LOOP, Map.TimeOfDay[CurrentMapLayer]);
	}
#endif

	//
	// Game logic part
	//
	if (!GamePaused && NetworkInSync && !SkipGameCycle) {
		SinglePlayerReplayEachCycle();
		++GameCycle;
		MultiPlayerReplayEachCycle();
		NetworkCommands(); // Get network commands
		TriggersEachCycle();// handle triggers
		UnitActions();      // handle units
		MissileActions();   // handle missiles
		PlayersEachCycle(); // handle players
		UpdateTimer();      // update game timer


		//
		// Work todo each second.
		// Split into different frames, to reduce cpu time.
		// Increment mana of magic units.
		// Update mini-map.
		// Update map fog of war.
		// Call AI.
		// Check game goals.
		// Check rescue of units.
		//
		switch (GameCycle % CYCLES_PER_SECOND) {
			case 0: // At cycle 0, start all ai players...
				if (GameCycle == 0) {
					for (int player = 0; player < NumPlayers; ++player) {
						PlayersEachSecond(player);
					}
				}
				break;
			case 1:
				break;
			case 2:
				break;
			case 3: // minimap update
				UI.Minimap.UpdateCache = true;
				break;
			case 4:
				break;
			case 5: // forest grow
				Map.RegenerateForest();
				break;
			case 6: // overtaking units
				RescueUnits();
				break;
			//Wyrmgus start
			/*
			default: {
				// FIXME: assume that NumPlayers < (CYCLES_PER_SECOND - 7)
				int player = (GameCycle % CYCLES_PER_SECOND) - 7;
				Assert(player >= 0);
				if (player < NumPlayers) {
					PlayersEachSecond(player);
				}
			}
			*/
			//Wyrmgus end
		}
		
		//Wyrmgus start
		int player = (GameCycle - 1) % CYCLES_PER_SECOND;
		Assert(player >= 0);
		if (player < NumPlayers) {
			PlayersEachSecond(player);
			if ((player + CYCLES_PER_SECOND) < NumPlayers) {
				PlayersEachSecond(player + CYCLES_PER_SECOND);
			}
		}
		
		player = (GameCycle - 1) % CYCLES_PER_MINUTE;
		Assert(player >= 0);
		if (player < NumPlayers) {
			PlayersEachMinute(player);
		}
		//Wyrmgus end
		
		//Wyrmgus start
		for (size_t z = 0; z < Map.Fields.size(); ++z) {
			if (GameSettings.Inside || GameSettings.NoTimeOfDay || !Map.TimeOfDaySeconds[z]) {
				// indoors it is always dark (maybe would be better to allow a special setting to have bright indoor places?
				Map.TimeOfDay[z] = NoTimeOfDay; // make indoors have no time of day setting until it is possible to make light sources change their surrounding "time of day"
				continue;
			}
			if (GameCycle > 0 && GameCycle % (CYCLES_PER_SECOND * Map.TimeOfDaySeconds[z]) == 0) { 
				Map.TimeOfDay[z] += 1;
				if (Map.TimeOfDay[z] == MaxTimesOfDay) {
					Map.TimeOfDay[z] = 1;
				}

#ifdef USE_OAML
				if (enableOAML && oaml && z == CurrentMapLayer) {
					// Time of day can change our main music loop, if the current playing track is set for this
					SetMusicCondition(OAML_CONDID_MAIN_LOOP, Map.TimeOfDay[z]);
				}
#endif

				//update the sight of all units
				for (CUnitManager::Iterator it = UnitManager.begin(); it != UnitManager.end(); ++it) {
					CUnit *unit = *it;
					if (
						unit && unit->IsAlive() && unit->MapLayer == z &&
						(
							((Map.TimeOfDay[z] == MorningTimeOfDay || Map.TimeOfDay[z] == DuskTimeOfDay) && unit->Variable[DAYSIGHTRANGEBONUS_INDEX].Value != 0) // if has day sight bonus and is entering or exiting day
							|| ((Map.TimeOfDay[z] == FirstWatchTimeOfDay || Map.TimeOfDay[z] == DawnTimeOfDay) && unit->Variable[NIGHTSIGHTRANGEBONUS_INDEX].Value != 0) // if has night sight bonus and is entering or exiting night
						)
					) {
						MapUnmarkUnitSight(*unit);
						UpdateUnitSightRange(*unit);
						MapMarkUnitSight(*unit);
					}
				}
			}
		}
		//Wyrmgus end
		
		//Wyrmgus start
//		if (Preference.AutosaveMinutes != 0 && !IsNetworkGame() && GameCycle > 0 && (GameCycle % (CYCLES_PER_SECOND * 60 * Preference.AutosaveMinutes)) == 0) { // autosave every X minutes, if the option is enabled
		if (Preference.AutosaveMinutes != 0 && !IsNetworkGame() && !GrandStrategy && GameCycle > 0 && (GameCycle % (CYCLES_PER_MINUTE * Preference.AutosaveMinutes)) == 0) { // autosave every X minutes, if the option is enabled
		//Wyrmgus end
			UI.StatusLine.Set(_("Autosave"));
			//Wyrmgus start
//			SaveGame("autosave.sav");
			CclCommand("if (RunSaveGame ~= nil) then RunSaveGame(\"autosave.sav\") end;");
			//Wyrmgus end
		}
	}

	UpdateMessages();     // update messages
	ParticleManager.update(); // handle particles
	CheckMusicFinished(); // Check for next song

	if (FastForwardCycle <= GameCycle || !(GameCycle & 0x3f)) {
		WaitEventsOneFrame();
	}

	if (!NetworkInSync) {
		NetworkRecover(); // recover network
	}
}