1 // This file is part of Glest (www.glest.org)
2 //
3 // Copyright (C) 2001-2008 Martiño Figueroa
4 //
5 // You can redistribute this code and/or modify it under
6 // the terms of the GNU General Public License as published
7 // by the Free Software Foundation; either version 2 of the
8 // License, or (at your option) any later version
9 // ==============================================================
10
11 #include "game.h"
12
13 #include "config.h"
14 #include "renderer.h"
15 #include "particle_renderer.h"
16 #include "commander.h"
17 #include "battle_end.h"
18 #include "sound_renderer.h"
19 #include "profiler.h"
20 #include "core_data.h"
21 #include "metrics.h"
22 #include "faction.h"
23 #include "network_manager.h"
24 #include "checksum.h"
25 #include "auto_test.h"
26 #include "menu_state_keysetup.h"
27 #include "video_player.h"
28 #include "compression_utils.h"
29 #include "cache_manager.h"
30
31 #include "leak_dumper.h"
32
33 using namespace Shared::Graphics;
34 using namespace Shared::Util;
35 using namespace Shared::Platform;
36 using namespace Shared::CompressionUtil;
37
38 namespace Glest{ namespace Game{
39
40 string GameSettings::playerDisconnectedText = "";
41 Game *thisGamePtr = NULL;
42
43 // =====================================================
44 // class Game
45 // =====================================================
46
47 // ===================== PUBLIC ========================
48
49 const float PHOTO_MODE_MAXHEIGHT = 500.0;
50
51 const int CREATE_NEW_TEAM = -100;
52 const int CANCEL_SWITCH_TEAM = -1;
53
54 const int CANCEL_DISCONNECT_PLAYER = -1;
55
56 const float Game::highlightTime= 0.5f;
57
58 int fadeMusicMilliseconds = 3500;
59
60 // Check every x seconds if we should switch disconnected players to AI
61 const int NETWORK_PLAYER_CONNECTION_CHECK_SECONDS = 5;
62
63 int GAME_STATS_DUMP_INTERVAL = 60 * 10;
64
Game()65 Game::Game() : ProgramState(NULL) {
66 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
67
68 originalDisplayMsgCallback = NULL;
69 aiInterfaces.clear();
70 videoPlayer = NULL;
71 playingStaticVideo = false;
72
73 mouse2d=0;
74 mouseX=0;
75 mouseY=0;
76 updateFps=0;
77 lastUpdateFps=0;
78 avgUpdateFps=0;
79 framesToCatchUpAsClient=0;
80 framesToSlowDownAsClient=0;
81 totalRenderFps=0;
82 renderFps=0;
83 lastRenderFps=0;
84 avgRenderFps=0;
85 currentAvgRenderFpsTotal=0;
86 paused=false;
87 networkPauseGameForLaggedClientsRequested=false;
88 networkResumeGameForLaggedClientsRequested=false;
89 pausedForJoinGame=false;
90 pausedBeforeJoinGame=false;
91 pauseRequestSent=false;
92 resumeRequestSent=false;
93 pauseStateChanged=false;
94 gameOver=false;
95 renderNetworkStatus=false;
96 renderInGamePerformance=false;
97 showFullConsole=false;
98 setMarker=false;
99 cameraDragAllowed=false;
100 mouseMoved=false;
101 scrollSpeed=0;
102 camLeftButtonDown=false;
103 camRightButtonDown=false;
104 camUpButtonDown=false;
105 camDownButtonDown=false;
106 this->speed=1;
107 weatherParticleSystem=NULL;
108 isFirstRender=false;
109 quitTriggeredIndicator=false;
110 quitPendingIndicator=false;
111 original_updateFps=0;
112 original_cameraFps=0;
113 captureAvgTestStatus=false;
114 updateFpsAvgTest=0;
115 renderFpsAvgTest=0;
116 renderExtraTeamColor=0;
117 photoModeEnabled=false;
118 healthbarMode=hbvUndefined;
119 visibleHUD=false;
120 timeDisplay=false;
121 withRainEffect=false;
122 program=NULL;
123 gameStarted=false;
124 this->initialResumeSpeedLoops=false;
125
126 highlightCellTexture=NULL;
127 lastMasterServerGameStatsDump=0;
128 lastMaxUnitCalcTime=0;
129 lastRenderLog2d=0;
130 playerIndexDisconnect=0;
131 tickCount=0;
132 currentCameraFollowUnit=NULL;
133
134 popupMenu.setEnabled(false);
135 popupMenu.setVisible(false);
136
137 popupMenuSwitchTeams.setEnabled(false);
138 popupMenuSwitchTeams.setVisible(false);
139
140 popupMenuDisconnectPlayer.setEnabled(false);
141 popupMenuDisconnectPlayer.setVisible(false);
142
143 switchTeamConfirmMessageBox.setEnabled(false);
144 disconnectPlayerConfirmMessageBox.setEnabled(false);
145
146 disconnectPlayerIndexMap.clear();
147
148 exitGamePopupMenuIndex = -1;
149 joinTeamPopupMenuIndex = -1;
150 pauseGamePopupMenuIndex = -1;
151 saveGamePopupMenuIndex = -1;
152 loadGamePopupMenuIndex = -1;
153 keyboardSetupPopupMenuIndex = -1;
154 disconnectPlayerPopupMenuIndex = -1;
155
156 isMarkCellEnabled = false;
157 isMarkCellTextEnabled = false;
158
159 markCellTexture = NULL;
160 isUnMarkCellEnabled = false;
161 unmarkCellTexture = NULL;
162
163 masterserverMode = false;
164 currentUIState=NULL;
165 currentAmbientSound=NULL;
166 //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
167
168 loadGameNode = NULL;
169 lastworldFrameCountForReplay = -1;
170 lastNetworkPlayerConnectionCheck = time(NULL);
171 inJoinGameLoading = false;
172 quitGameCalled = false;
173 disableSpeedChange = false;
174
175 for( int i=0;i<GameConstants::networkSmoothInterval;i++){
176 receivedTooEarlyInFrames[i]=-1;
177 framesNeededToWaitForServerMessage[i]=-1;
178 }
179
180 fadeMusicMilliseconds = Config::getInstance().getInt("GameStartStopFadeSoundMilliseconds",intToStr(fadeMusicMilliseconds).c_str());
181 GAME_STATS_DUMP_INTERVAL = Config::getInstance().getInt("GameStatsDumpIntervalSeconds",intToStr(GAME_STATS_DUMP_INTERVAL).c_str());
182 }
183
resetMembers()184 void Game::resetMembers() {
185 Unit::setGame(this);
186 gameStarted = false;
187 this->initialResumeSpeedLoops = false;
188
189 original_updateFps = GameConstants::updateFps;
190 original_cameraFps = GameConstants::cameraFps;
191 GameConstants::updateFps= 40;
192 GameConstants::cameraFps= 100;
193 captureAvgTestStatus = false;
194 updateFpsAvgTest=0;
195 renderFpsAvgTest=0;
196 lastRenderLog2d = 0;
197 playerIndexDisconnect=0;
198 lastMasterServerGameStatsDump=0;
199 highlightCellTexture=NULL;
200 totalRenderFps =0;
201 lastMaxUnitCalcTime =0;
202 renderExtraTeamColor =0;
203
204 mouseMoved= false;
205 quitTriggeredIndicator = false;
206 quitPendingIndicator=false;
207 originalDisplayMsgCallback = NULL;
208 thisGamePtr = this;
209
210 popupMenu.setEnabled(false);
211 popupMenu.setVisible(false);
212
213 popupMenuSwitchTeams.setEnabled(false);
214 popupMenuSwitchTeams.setVisible(false);
215
216 popupMenuDisconnectPlayer.setEnabled(false);
217 popupMenuDisconnectPlayer.setVisible(false);
218
219 switchTeamConfirmMessageBox.setEnabled(false);
220 disconnectPlayerConfirmMessageBox.setEnabled(false);
221
222 disconnectPlayerIndexMap.clear();
223
224 exitGamePopupMenuIndex = -1;
225 joinTeamPopupMenuIndex = -1;
226 pauseGamePopupMenuIndex = -1;
227 saveGamePopupMenuIndex = -1;
228 loadGamePopupMenuIndex = -1;
229 keyboardSetupPopupMenuIndex = -1;
230 disconnectPlayerPopupMenuIndex = -1;
231
232 isMarkCellEnabled = false;
233 isMarkCellTextEnabled = false;
234
235 markCellTexture = NULL;
236 isUnMarkCellEnabled = false;
237 unmarkCellTexture = NULL;
238
239 currentUIState = NULL;
240
241 scrollSpeed = Config::getInstance().getFloat("UiScrollSpeed","1.5");
242 photoModeEnabled = Config::getInstance().getBool("PhotoMode","false");
243 healthbarMode = Config::getInstance().getInt("HealthBarMode","4");
244 visibleHUD = Config::getInstance().getBool("VisibleHud","true");
245 timeDisplay = Config::getInstance().getBool("TimeDisplay","true");
246 withRainEffect = Config::getInstance().getBool("RainEffect","true");
247 //MIN_RENDER_FPS_ALLOWED = Config::getInstance().getInt("MIN_RENDER_FPS_ALLOWED",intToStr(MIN_RENDER_FPS_ALLOWED).c_str());
248
249 mouseX=0;
250 mouseY=0;
251 mouse2d= 0;
252 loadingText="";
253 weatherParticleSystem= NULL;
254 updateFps=0;
255 renderFps=0;
256 lastUpdateFps=0;
257 framesToCatchUpAsClient=0;
258 framesToSlowDownAsClient=0;
259 lastRenderFps=-1;
260 avgUpdateFps=-1;
261 avgRenderFps=-1;
262 currentAvgRenderFpsTotal=0;
263 tickCount=0;
264 paused= false;
265 networkPauseGameForLaggedClientsRequested=false;
266 networkResumeGameForLaggedClientsRequested=false;
267 pausedForJoinGame=false;
268 pausedBeforeJoinGame=false;
269 resumeRequestSent=false;
270 pauseRequestSent=false;
271 pauseStateChanged=false;
272 gameOver= false;
273 renderNetworkStatus= false;
274 renderInGamePerformance=false;
275 this->speed= 1;
276 showFullConsole= false;
277 setMarker = false;
278 cameraDragAllowed=false;
279 camLeftButtonDown=false;
280 camRightButtonDown=false;
281 camUpButtonDown=false;
282 camDownButtonDown=false;
283
284 currentCameraFollowUnit=NULL;
285 currentAmbientSound=NULL;
286 //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
287
288 loadGameNode = NULL;
289 lastworldFrameCountForReplay = -1;
290
291 lastNetworkPlayerConnectionCheck = time(NULL);
292
293 inJoinGameLoading = false;
294 quitGameCalled = false;
295 disableSpeedChange = false;
296
297 for( int i=0;i<GameConstants::networkSmoothInterval;i++){
298 receivedTooEarlyInFrames[i]=-1;
299 framesNeededToWaitForServerMessage[i]=-1;
300 }
301
302
303 fadeMusicMilliseconds = Config::getInstance().getInt("GameStartStopFadeSoundMilliseconds",intToStr(fadeMusicMilliseconds).c_str());
304 GAME_STATS_DUMP_INTERVAL = Config::getInstance().getInt("GameStatsDumpIntervalSeconds",intToStr(GAME_STATS_DUMP_INTERVAL).c_str());
305
306 Logger &logger= Logger::getInstance();
307 logger.showProgress();
308 }
309
Game(Program * program,const GameSettings * gameSettings,bool masterserverMode)310 Game::Game(Program *program, const GameSettings *gameSettings,bool masterserverMode):
311 ProgramState(program), lastMousePos(0), isFirstRender(true)
312 {
313 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
314 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
315
316 this->masterserverMode = masterserverMode;
317 videoPlayer = NULL;
318 playingStaticVideo = false;
319 highlightCellTexture = NULL;
320 playerIndexDisconnect=0;
321 updateFpsAvgTest=0;
322 renderFpsAvgTest=0;
323 cameraDragAllowed=false;
324
325 if(this->masterserverMode == true) {
326 printf("Starting a new game...\n");
327 }
328
329 this->program = program;
330 resetMembers();
331 this->gameSettings= *gameSettings;
332
333 Lang::getInstance().setAllowNativeLanguageTechtree(this->gameSettings.getNetworkAllowNativeLanguageTechtree());
334
335 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
336 }
337
endGame()338 void Game::endGame() {
339 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
340 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
341
342 quitGame();
343 sleep(0);
344
345 Object::setStateCallback(NULL);
346 thisGamePtr = NULL;
347 if(originalDisplayMsgCallback != NULL) {
348 NetworkInterface::setDisplayMessageFunction(originalDisplayMsgCallback);
349 }
350
351 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
352
353 Logger &logger= Logger::getInstance();
354 Renderer &renderer= Renderer::getInstance();
355
356 logger.clearHints();
357 logger.loadLoadingScreen("");
358 logger.setState(Lang::getInstance().getString("Deleting"));
359 //logger.add("Game", true);
360 logger.add(Lang::getInstance().getString("LogScreenGameLoading","",true), false);
361 logger.hideProgress();
362
363 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
364
365 // Cannot Fade because sound files will be deleted below
366 SoundRenderer::getInstance().stopAllSounds(fadeMusicMilliseconds);
367
368 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
369
370 // deleteValues(aiInterfaces.begin(), aiInterfaces.end());
371 // aiInterfaces.clear();
372
373 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
374
375 gui.end(); //selection must be cleared before deleting units
376
377 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
378
379 // world.end(); //must die before selection because of referencers
380
381 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] aiInterfaces.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,aiInterfaces.size());
382
383 // MUST DO THIS LAST!!!! Because objects above have pointers to things like
384 // unit particles and fade them out etc and this end method deletes the original
385 // object pointers.
386 renderer.endGame(false);
387
388 GameConstants::updateFps = original_updateFps;
389 GameConstants::cameraFps = original_cameraFps;
390
391 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
392
393 Unit::setGame(NULL);
394
395 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ==== END GAME ==== getCurrentPixelByteCount() = " MG_SIZE_T_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderer.getCurrentPixelByteCount());
396 if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"==== END GAME ====\n");
397
398 FileCRCPreCacheThread * &preCacheCRCThreadPtr = CacheManager::getCachedItem< FileCRCPreCacheThread * >(GameConstants::preCacheThreadCacheLookupKey);
399 if(preCacheCRCThreadPtr != NULL) {
400 preCacheCRCThreadPtr->setPauseForGame(false);
401 }
402
403 //this->program->reInitGl();
404 //renderer.reinitAll();
405 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
406 }
407
~Game()408 Game::~Game() {
409 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
410 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
411
412 quitGame();
413
414 Object::setStateCallback(NULL);
415 thisGamePtr = NULL;
416 if(originalDisplayMsgCallback != NULL) {
417 NetworkInterface::setDisplayMessageFunction(originalDisplayMsgCallback);
418 }
419
420 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
421
422 Logger &logger= Logger::getInstance();
423 Renderer &renderer= Renderer::getInstance();
424
425 logger.loadLoadingScreen("");
426 logger.setState(Lang::getInstance().getString("Deleting"));
427 //logger.add("Game", true);
428 logger.add(Lang::getInstance().getString("LogScreenGameLoading","",true), false);
429 logger.hideProgress();
430
431 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
432
433 // Cannot Fade because sound files will be deleted below
434 SoundRenderer::getInstance().stopAllSounds();
435
436 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
437
438 masterController.clearSlaves(true);
439 deleteValues(aiInterfaces.begin(), aiInterfaces.end());
440 aiInterfaces.clear();
441
442 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
443
444 gui.end(); //selection must be cleared before deleting units
445
446 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
447
448 world.end(); //must die before selection because of referencers
449
450 BaseColorPickEntity::resetUniqueColors();
451
452 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] aiInterfaces.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,aiInterfaces.size());
453
454 delete videoPlayer;
455 videoPlayer = NULL;
456 playingStaticVideo = false;
457
458 // MUST DO THIS LAST!!!! Because objects above have pointers to things like
459 // unit particles and fade them out etc and this end method deletes the original
460 // object pointers.
461 renderer.endGame(true);
462 BaseColorPickEntity::cleanupPBO();
463
464 GameConstants::updateFps = original_updateFps;
465 GameConstants::cameraFps = original_cameraFps;
466
467 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
468
469 Unit::setGame(NULL);
470
471 Lang::getInstance().setAllowNativeLanguageTechtree(true);
472
473 FileCRCPreCacheThread * &preCacheCRCThreadPtr = CacheManager::getCachedItem< FileCRCPreCacheThread * >(GameConstants::preCacheThreadCacheLookupKey);
474 if(preCacheCRCThreadPtr != NULL) {
475 preCacheCRCThreadPtr->setPauseForGame(false);
476 }
477
478 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ==== END GAME ==== getCurrentPixelByteCount() = " MG_SIZE_T_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderer.getCurrentPixelByteCount());
479 if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"==== END GAME ====\n");
480
481 //this->program->reInitGl();
482 //renderer.reinitAll();
483 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
484 }
485
showTranslatedTechTree() const486 bool Game::showTranslatedTechTree() const {
487 return this->gameSettings.getNetworkAllowNativeLanguageTechtree();
488 }
489
quitTriggered()490 bool Game::quitTriggered() {
491 return quitTriggeredIndicator;
492 }
493
quitAndToggleState()494 Stats Game::quitAndToggleState() {
495 //quitGame();
496 //Program *program = game->getProgram();
497 return quitGame();
498 //Game::exitGameState(program, endStats);
499 }
500
501 // ==================== init and load ====================
502
ErrorDisplayMessage(const char * msg,bool exitApp)503 int Game::ErrorDisplayMessage(const char *msg, bool exitApp) {
504 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,msg);
505
506 if(thisGamePtr != NULL) {
507 string text = msg;
508 thisGamePtr->showErrorMessageBox(text, "Error detected", false);
509 }
510
511 return 0;
512 }
513
findFactionLogoTexture(const GameSettings * settings,Logger * logger,string factionLogoFilter,bool useTechDefaultIfFilterNotFound)514 Texture2D * Game::findFactionLogoTexture(const GameSettings *settings, Logger *logger,string factionLogoFilter, bool useTechDefaultIfFilterNotFound) {
515 Texture2D *result = NULL;
516 string logoFilename = Game::findFactionLogoFile(settings, logger,factionLogoFilter);
517 if(logoFilename == "" && factionLogoFilter != "" && useTechDefaultIfFilterNotFound == true) {
518 logoFilename = Game::findFactionLogoFile(settings, logger);
519 }
520
521 result = Renderer::findTexture(logoFilename);
522
523 return result;
524 }
525
extractScenarioLogoFile(const GameSettings * settings,string & result,bool & loadingImageUsed,Logger * logger,string factionLogoFilter)526 string Game::extractScenarioLogoFile(const GameSettings *settings, string &result,
527 bool &loadingImageUsed, Logger *logger, string factionLogoFilter) {
528 string scenarioDir = "";
529 if(settings->getScenarioDir() != "") {
530 scenarioDir = settings->getScenarioDir();
531 if(EndsWith(scenarioDir, ".xml") == true) {
532 scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4);
533 scenarioDir = scenarioDir.erase(scenarioDir.size() - settings->getScenario().size(), settings->getScenario().size() + 1);
534 }
535
536 //printf("!!! extractScenarioLogoFile scenarioDir [%s] factionLogoFilter [%s]\n",scenarioDir.c_str(),factionLogoFilter.c_str());
537
538 vector<string> loadScreenList;
539 string logoFullPathFilter = scenarioDir + factionLogoFilter;
540 findAll(logoFullPathFilter, loadScreenList, false, false);
541 if(loadScreenList.empty() == false) {
542 int bestLogoIndex = 0;
543
544 if(loadScreenList.size() > 1 && EndsWith(factionLogoFilter, ".xml") == false) {
545 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nLooking for best logo from a list of: " MG_SIZE_T_SPECIFIER " using filter: [%s]\n",loadScreenList.size(),logoFullPathFilter.c_str());
546
547 int bestMinWidthDiff = INT_MAX;
548 int bestMinHeightDiff = INT_MAX;
549 // Now find the best texture for our screen
550 // Texture2D *result = preloadTexture(logoFilename);
551 for(unsigned int logoIndex = 0; logoIndex < loadScreenList.size(); ++logoIndex) {
552 string senarioLogo = scenarioDir + loadScreenList[bestLogoIndex];
553 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] looking for loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,senarioLogo.c_str());
554
555 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Looking for best logo: %u [%s]\n",logoIndex,senarioLogo.c_str());
556
557 if(fileExists(senarioLogo) == true) {
558 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,senarioLogo.c_str());
559
560 Texture2D *checkLogo = Renderer::preloadTexture(senarioLogo);
561 if(checkLogo != NULL) {
562 const Metrics &metrics= Metrics::getInstance();
563 int minWidthDifference = abs(metrics.getScreenW() - checkLogo->getPixmapConst()->getW());
564 int minHeightDifference = abs(metrics.getScreenH() - checkLogo->getPixmapConst()->getH());
565
566 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Logo info: %d x %d (%d,%d)\n",checkLogo->getPixmapConst()->getW(),checkLogo->getPixmapConst()->getH(),minWidthDifference,minHeightDifference);
567
568 if(minWidthDifference < bestMinWidthDiff) {
569 bestMinWidthDiff = minWidthDifference;
570
571 bestLogoIndex = logoIndex;
572 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 New best logo is [%s]\n",senarioLogo.c_str());
573 }
574 else if(minWidthDifference == bestMinWidthDiff &&
575 minHeightDifference < bestMinHeightDiff) {
576 bestMinHeightDiff = minHeightDifference;
577
578 bestLogoIndex = logoIndex;
579 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 New best logo is [%s]\n",senarioLogo.c_str());
580 }
581 }
582 }
583 }
584 }
585
586 string senarioLogo = scenarioDir + loadScreenList[bestLogoIndex];
587 if(fileExists(senarioLogo) == true) {
588 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] found scenario loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,senarioLogo.c_str());
589
590 result = senarioLogo;
591 if(logger != NULL) {
592 logger->loadLoadingScreen(result);
593 }
594 loadingImageUsed=true;
595 }
596 }
597 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,settings->getScenarioDir().c_str(),settings->getScenario().c_str(),scenarioDir.c_str());
598 }
599 return scenarioDir;
600 }
601
extractFactionLogoFile(bool & loadingImageUsed,string factionName,string scenarioDir,string techName,Logger * logger,string factionLogoFilter)602 string Game::extractFactionLogoFile(bool &loadingImageUsed, string factionName,
603 string scenarioDir, string techName, Logger *logger, string factionLogoFilter) {
604 string result = "";
605 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Searching for faction loading screen\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
606
607 if(factionName == formatString(GameConstants::OBSERVER_SLOTNAME)) {
608 string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
609 const string factionLogo = data_path + "data/core/misc_textures/observer.jpg";
610 //printf("In [%s::%s Line: %d] looking for loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,factionLogo.c_str());
611
612 if(fileExists(factionLogo) == true) {
613 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,factionLogo.c_str());
614
615 result = factionLogo;
616 if(logger != NULL) {
617 logger->loadLoadingScreen(result);
618 }
619 loadingImageUsed = true;
620 }
621 }
622 //else if(settings->getFactionTypeName(i) == formatString(GameConstants::RANDOMFACTION_SLOTNAME)) {
623 else if(factionName == formatString(GameConstants::RANDOMFACTION_SLOTNAME)) {
624 string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
625 const string factionLogo = data_path + "data/core/misc_textures/random.jpg";
626
627 if(fileExists(factionLogo) == true) {
628 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,factionLogo.c_str());
629
630 result = factionLogo;
631 if(logger != NULL) {
632 logger->loadLoadingScreen(result);
633 }
634 loadingImageUsed = true;
635 }
636 }
637 else {
638 Config &config = Config::getInstance();
639 vector<string> pathList = config.getPathListForType(ptTechs,scenarioDir);
640 for(int idx = 0; idx < (int)pathList.size(); idx++) {
641 string currentPath = pathList[idx];
642 endPathWithSlash(currentPath);
643 //string path = currentPath + techName + "/" + "factions" + "/" + settings->getFactionTypeName(i);
644 string path = currentPath + techName + "/" + "factions" + "/" + factionName;
645 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] possible loading screen dir '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str());
646 if(isdir(path.c_str()) == true) {
647 endPathWithSlash(path);
648
649 vector<string> loadScreenList;
650 string logoFullPathFilter = path + factionLogoFilter;
651 findAll(logoFullPathFilter, loadScreenList, false, false);
652 if(loadScreenList.empty() == false) {
653 int bestLogoIndex = 0;
654
655 if(loadScreenList.size() > 1 && EndsWith(factionLogoFilter, ".xml") == false) {
656 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nLooking for best logo from a list of: " MG_SIZE_T_SPECIFIER " using filter: [%s]\n",loadScreenList.size(),logoFullPathFilter.c_str());
657
658
659 int bestMinWidthDiff = INT_MAX;
660 int bestMinHeightDiff = INT_MAX;
661 // Now find the best texture for our screen
662 // Texture2D *result = preloadTexture(logoFilename);
663 for(unsigned int logoIndex = 0; logoIndex < (unsigned int)loadScreenList.size(); ++logoIndex) {
664 string factionLogo = path + loadScreenList[logoIndex];
665 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] looking for loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,factionLogo.c_str());
666
667 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Looking for best logo: %u [%s]\n",logoIndex,factionLogo.c_str());
668
669 if(fileExists(factionLogo) == true) {
670 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,factionLogo.c_str());
671
672 Texture2D *checkLogo = Renderer::preloadTexture(factionLogo);
673 if(checkLogo != NULL) {
674 const Metrics &metrics= Metrics::getInstance();
675 int minWidthDifference = abs(metrics.getScreenW() - checkLogo->getPixmapConst()->getW());
676 int minHeightDifference = abs(metrics.getScreenH() - checkLogo->getPixmapConst()->getH());
677
678 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Logo info: %d x %d (%d,%d)\n",checkLogo->getPixmapConst()->getW(),checkLogo->getPixmapConst()->getH(),minWidthDifference,minHeightDifference);
679
680 if(minWidthDifference < bestMinWidthDiff) {
681 bestMinWidthDiff = minWidthDifference;
682
683 bestLogoIndex = logoIndex;
684 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 New best logo is [%s]\n",factionLogo.c_str());
685 }
686 else if(minWidthDifference == bestMinWidthDiff &&
687 minHeightDifference < bestMinHeightDiff) {
688 bestMinHeightDiff = minHeightDifference;
689
690 bestLogoIndex = logoIndex;
691 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 New best logo is [%s]\n",factionLogo.c_str());
692 }
693 }
694 }
695 }
696 }
697
698 string factionLogo = path + loadScreenList[bestLogoIndex];
699 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] looking for loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,factionLogo.c_str());
700
701 if(fileExists(factionLogo) == true) {
702 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,factionLogo.c_str());
703
704 result = factionLogo;
705 if(logger != NULL) {
706 logger->loadLoadingScreen(result);
707 }
708 loadingImageUsed = true;
709 break;
710 }
711 }
712 // Check if this is a linked faction
713 else {
714 //!!!
715 string factionXMLFile = path + factionName + ".xml";
716
717 //printf("A factionXMLFile [%s]\n",factionXMLFile.c_str());
718
719 if(fileExists(factionXMLFile) == true) {
720 XmlTree xmlTreeFaction(XML_RAPIDXML_ENGINE);
721 std::map<string,string> mapExtraTagReplacementValues;
722 xmlTreeFaction.load(factionXMLFile, Properties::getTagReplacementValues(&mapExtraTagReplacementValues),true,true);
723
724 const XmlNode *rootNode= xmlTreeFaction.getRootNode();
725
726 //printf("B factionXMLFile [%s] root name [%s] root first child name [%s]\n",factionXMLFile.c_str(),rootNode->getName().c_str(),rootNode->getChild(0)->getName().c_str());
727 //printf("B factionXMLFile [%s] root name [%s]\n",factionXMLFile.c_str(),rootNode->getName().c_str());
728 if(rootNode->hasChild("link") == true) {
729 rootNode = rootNode->getChild("link");
730 }
731 if(rootNode->getName() == "link" && rootNode->hasChild("techtree") == true) {
732 const XmlNode *linkNode = rootNode;
733
734 //printf("C factionXMLFile [%s]\n",factionXMLFile.c_str());
735
736 //if(linkNode->hasChild("techtree") == true) {
737 const XmlNode *techtreeNode = linkNode->getChild("techtree");
738
739 string linkedTechTreeName = techtreeNode->getAttribute("name")->getValue();
740
741 //printf("D factionXMLFile [%s] linkedTechTreeName [%s]\n",factionXMLFile.c_str(),linkedTechTreeName.c_str());
742
743 if(linkedTechTreeName != "") {
744
745 string linkedTechTreePath=TechTree::findPath(linkedTechTreeName,pathList);
746 string techTreePath=linkedTechTreePath;
747 endPathWithSlash(techTreePath);
748
749 string linkedCurrentPath = techTreePath + "factions/" + factionName;
750 endPathWithSlash(linkedCurrentPath);
751 //string linkedTmppath= linkedCurrentPath + factionName +".xml";
752
753 path = linkedCurrentPath;
754 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] possible loading screen dir '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str());
755
756 //printf("D1 idx = %d\ncurrentPath [%s]\npath [%s]\npathList[idx] [%s]\n",idx,currentPath.c_str(),path.c_str(),pathList[idx].c_str());
757
758 if(isdir(path.c_str()) == true) {
759 endPathWithSlash(path);
760
761 //printf("E path [%s]\n",path.c_str());
762
763 loadScreenList.clear();
764 findAll(path + factionLogoFilter, loadScreenList, false, false);
765 if(loadScreenList.empty() == false) {
766 string factionLogo = path + loadScreenList[0];
767 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] looking for loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,factionLogo.c_str());
768
769 //printf("F factionLogo [%s]\n",factionLogo.c_str());
770
771 if(fileExists(factionLogo) == true) {
772 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,factionLogo.c_str());
773
774 result = factionLogo;
775 if(logger != NULL) {
776 logger->loadLoadingScreen(result);
777 }
778 loadingImageUsed = true;
779 break;
780 }
781 }
782 }
783 }
784 //}
785 }
786 }
787 }
788 }
789
790 if(loadingImageUsed == true) {
791 break;
792 }
793 }
794 }
795 //break;
796 //}
797 //}
798 return result;
799 }
800
extractTechLogoFile(string scenarioDir,string techName,bool & loadingImageUsed,Logger * logger,string factionLogoFilter)801 string Game::extractTechLogoFile(string scenarioDir, string techName,
802 bool &loadingImageUsed, Logger *logger,string factionLogoFilter) {
803 string result = "";
804 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Searching for tech loading screen\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
805 Config &config = Config::getInstance();
806 vector<string> pathList = config.getPathListForType(ptTechs, scenarioDir);
807 for(int idx = 0; idx < (int)pathList.size(); idx++) {
808 string currentPath = pathList[idx];
809 endPathWithSlash(currentPath);
810 string path = currentPath + techName;
811 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] possible loading screen dir '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str());
812 if(isdir(path.c_str()) == true) {
813 endPathWithSlash(path);
814
815 vector<string> loadScreenList;
816 findAll(path + factionLogoFilter, loadScreenList, false, false);
817 if(loadScreenList.empty() == false) {
818 string factionLogo = path + loadScreenList[0];
819 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] looking for loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,factionLogo.c_str());
820
821 if(fileExists(factionLogo) == true) {
822 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,factionLogo.c_str());
823
824 result = factionLogo;
825 if(logger != NULL) {
826 logger->loadLoadingScreen(result);
827 }
828 loadingImageUsed = true;
829 break;
830 }
831 }
832 }
833 if(loadingImageUsed == true) {
834 break;
835 }
836 }
837
838 return result;
839 }
840
loadHudTexture(const GameSettings * settings)841 void Game::loadHudTexture(const GameSettings *settings)
842 {
843 string factionName = "";
844 string techName = settings->getTech();
845 string scenarioDir = extractDirectoryPathFromFile(settings->getScenarioDir());
846 //printf("In loadHudTexture, scenarioDir [%s]\n",scenarioDir.c_str());
847
848 for(int i=0; i < settings->getFactionCount(); ++i ) {
849 if((settings->getFactionControl(i) == ctHuman) || (settings->getFactionControl(i) == ctNetwork
850 && settings->getThisFactionIndex() == i)){
851 factionName= settings->getFactionTypeName(i);
852 break;
853 }
854 }
855 if(factionName != "") {
856 bool hudFound = false;
857 Config &config= Config::getInstance();
858 vector<string> pathList= config.getPathListForType(ptTechs, scenarioDir);
859 for(int idx= 0; hudFound == false && idx < (int)pathList.size(); idx++){
860 string currentPath= pathList[idx];
861 endPathWithSlash(currentPath);
862
863 vector<string> hudList;
864 string path= currentPath + techName + "/" + "factions" + "/" + factionName;
865 endPathWithSlash(path);
866 findAll(path + GameConstants::HUD_SCREEN_FILE_FILTER, hudList, false, false);
867 if(hudList.empty() == false){
868 for(unsigned int hudIdx = 0; hudFound == false && hudIdx < (unsigned int)hudList.size(); ++hudIdx) {
869 string hudImageFileName= path + hudList[hudIdx];
870 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] looking for a HUD [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,hudImageFileName.c_str());
871 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled)
872 SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] looking for a HUD [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,hudImageFileName.c_str());
873
874 if(fileExists(hudImageFileName) == true){
875 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] found HUD image [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,hudImageFileName.c_str());
876 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled)
877 SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found HUD image [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,hudImageFileName.c_str());
878
879 Texture2D* texture= Renderer::findTexture(hudImageFileName);
880 gui.setHudTexture(texture);
881 hudFound = true;
882 //printf("Hud texture found! \n");
883 break;
884 }
885 }
886 }
887 }
888 }
889 }
890
findFactionLogoFile(const GameSettings * settings,Logger * logger,string factionLogoFilter)891 string Game::findFactionLogoFile(const GameSettings *settings, Logger *logger,
892 string factionLogoFilter) {
893 string result = "";
894 if(settings == NULL) {
895 result = "";
896 }
897 else {
898 string mapName = settings->getMap();
899 string tilesetName = settings->getTileset();
900 string techName = settings->getTech();
901 string scenarioName = settings->getScenario();
902 bool loadingImageUsed = false;
903
904 if(logger != NULL) {
905 logger->setState(Lang::getInstance().getString("Loading"));
906
907 if(scenarioName.empty()) {
908 string scenarioDir = extractDirectoryPathFromFile(settings->getScenarioDir());
909 TechTree techTree(Config::getInstance().getPathListForType(ptTechs,scenarioDir));
910
911 logger->setSubtitle(formatString(mapName) + " - " +
912 formatString(tilesetName) + " - " + formatString(techTree.getTranslatedName(techName)));
913 }
914 else {
915 logger->setSubtitle(formatString(scenarioName));
916 }
917 }
918
919 string scenarioDir = "";
920 bool skipCustomLoadScreen = false;
921 if(skipCustomLoadScreen == false) {
922 scenarioDir = extractScenarioLogoFile(settings, result, loadingImageUsed,
923 logger, factionLogoFilter);
924 }
925 // try to use a faction related loading screen
926 if(skipCustomLoadScreen == false && loadingImageUsed == false) {
927 for(int i=0; i < settings->getFactionCount(); ++i ) {
928 if( settings->getFactionControl(i) == ctHuman ||
929 (settings->getFactionControl(i) == ctNetwork && settings->getThisFactionIndex() == i)) {
930
931 result = extractFactionLogoFile(loadingImageUsed, settings->getFactionTypeName(i),
932 scenarioDir, techName, logger, factionLogoFilter);
933 break;
934 }
935 }
936 }
937
938 // try to use a tech related loading screen
939 if(skipCustomLoadScreen == false && loadingImageUsed == false){
940 result = extractTechLogoFile(scenarioDir, techName,
941 loadingImageUsed, logger, factionLogoFilter);
942 }
943 }
944 return result;
945 }
946
processTech(string techName)947 vector<Texture2D *> Game::processTech(string techName) {
948 vector<Texture2D *> logoFiles;
949 bool enableFactionTexturePreview = Config::getInstance().getBool("FactionPreview","true");
950 if(enableFactionTexturePreview) {
951 //string currentTechName_factionPreview = techName;
952
953 vector<string> factions;
954 vector<string> techPaths = Config::getInstance().getPathListForType(ptTechs);
955 for(int idx = 0; idx < (int)techPaths.size(); idx++) {
956 string &techPath = techPaths[idx];
957 endPathWithSlash(techPath);
958 findAll(techPath + techName + "/factions/*.", factions, false, false);
959
960 if(factions.empty() == false) {
961 for(unsigned int factionIdx = 0; factionIdx < (unsigned int)factions.size(); ++factionIdx) {
962 bool loadingImageUsed = false;
963 string currentFactionName_factionPreview = factions[factionIdx];
964
965 string factionLogo = Game::extractFactionLogoFile(
966 loadingImageUsed,
967 currentFactionName_factionPreview,
968 "",
969 techName,
970 NULL,
971 GameConstants::PREVIEW_SCREEN_FILE_FILTER);
972
973 if(factionLogo == "") {
974 factionLogo = Game::extractFactionLogoFile(
975 loadingImageUsed,
976 currentFactionName_factionPreview,
977 "",
978 techName,
979 NULL,
980 GameConstants::LOADING_SCREEN_FILE_FILTER);
981 }
982 if(factionLogo != "") {
983 Texture2D *texture = Renderer::preloadTexture(factionLogo);
984 logoFiles.push_back(texture);
985 }
986 }
987 }
988 }
989 }
990
991 return logoFiles;
992 }
993
load()994 void Game::load() {
995 load(lgt_All);
996 }
997
load(int loadTypes)998 void Game::load(int loadTypes) {
999 bool showPerfStats = Config::getInstance().getBool("ShowPerfStats","false");
1000 Chrono chronoPerf;
1001 if(showPerfStats) chronoPerf.start();
1002 char perfBuf[8096]="";
1003 std::vector<string> perfList;
1004
1005 if(showPerfStats) {
1006 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1007 perfList.push_back(perfBuf);
1008 }
1009
1010 FileCRCPreCacheThread * &preCacheCRCThreadPtr = CacheManager::getCachedItem< FileCRCPreCacheThread * >(GameConstants::preCacheThreadCacheLookupKey);
1011 if(preCacheCRCThreadPtr != NULL) {
1012 preCacheCRCThreadPtr->setPauseForGame(true);
1013 }
1014
1015 std::map<string,vector<pair<string, string> > > loadedFileList;
1016 originalDisplayMsgCallback = NetworkInterface::getDisplayMessageFunction();
1017 NetworkInterface::setDisplayMessageFunction(ErrorDisplayMessage);
1018
1019 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] loadTypes = %d, gameSettings = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,loadTypes,this->gameSettings.toString().c_str());
1020
1021 SoundRenderer &soundRenderer= SoundRenderer::getInstance();
1022 soundRenderer.stopAllSounds(fadeMusicMilliseconds);
1023
1024 BaseColorPickEntity::resetUniqueColors();
1025
1026 Config &config = Config::getInstance();
1027 Logger &logger= Logger::getInstance();
1028
1029 string mapName= gameSettings.getMap();
1030 string tilesetName= gameSettings.getTileset();
1031 string techName= gameSettings.getTech();
1032 string scenarioName= gameSettings.getScenario();
1033 string data_path= getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
1034 // loadHints
1035
1036 if(data_path != ""){
1037 endPathWithSlash(data_path);
1038 }
1039
1040 string user_data_path = config.getString("UserData_Root","");
1041 if(user_data_path != "") {
1042 endPathWithSlash(user_data_path);
1043 }
1044
1045 string englishFile=getGameCustomCoreDataPath(data_path, "data/lang/hint/hint_"+Lang::getInstance().getDefaultLanguage()+".lng");
1046 string languageFile=getGameCustomCoreDataPath(data_path, "data/lang/hint/hint_"+ Lang::getInstance().getLanguage() +".lng");
1047 string languageFileUserData=user_data_path + "data/lang/hint/hint_"+ Lang::getInstance().getLanguage() +".lng";
1048
1049 if(fileExists(languageFileUserData) == true){
1050 languageFile=languageFileUserData;
1051 }
1052 if(fileExists(languageFile) == false){
1053 // if there is no language specific file use english instead
1054 languageFile=englishFile;
1055 }
1056 if(fileExists(englishFile) == false){
1057 SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] file [%s] not found\n",__FILE__,__FUNCTION__,__LINE__,englishFile.c_str());
1058 }
1059 else {
1060 logger.loadGameHints(englishFile,languageFile,true);
1061
1062 ::Shared::Platform::Window::handleEvent();
1063 SDL_PumpEvents();
1064 }
1065
1066 if((loadTypes & lgt_FactionPreview) == lgt_FactionPreview) {
1067 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1068 Game::findFactionLogoFile(&gameSettings, &logger);
1069
1070 ::Shared::Platform::Window::handleEvent();
1071 SDL_PumpEvents();
1072 }
1073
1074 if(showPerfStats) {
1075 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1076 perfList.push_back(perfBuf);
1077 }
1078
1079 loadHudTexture(&gameSettings);
1080
1081 const string markCellTextureFilename = data_path + "data/core/misc_textures/mark_cell.png";
1082 markCellTexture = Renderer::findTexture(markCellTextureFilename);
1083 const string unmarkCellTextureFilename = data_path + "data/core/misc_textures/unmark_cell.png";
1084 unmarkCellTexture = Renderer::findTexture(unmarkCellTextureFilename);
1085 const string highlightCellTextureFilename = data_path + "data/core/misc_textures/pointer.png";
1086 highlightCellTexture = Renderer::findTexture(highlightCellTextureFilename);
1087
1088 string scenarioDir = "";
1089 if(gameSettings.getScenarioDir() != "") {
1090 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1091 scenarioDir = gameSettings.getScenarioDir();
1092 if(EndsWith(scenarioDir, ".xml") == true) {
1093 scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4);
1094 scenarioDir = scenarioDir.erase(scenarioDir.size() - gameSettings.getScenario().size(), gameSettings.getScenario().size() + 1);
1095 }
1096 }
1097
1098 if(showPerfStats) {
1099 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1100 perfList.push_back(perfBuf);
1101 }
1102
1103 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1104
1105 //tileset
1106 if((loadTypes & lgt_TileSet) == lgt_TileSet) {
1107 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1108 world.loadTileset( config.getPathListForType(ptTilesets,scenarioDir),
1109 tilesetName, &checksum, loadedFileList);
1110 }
1111
1112 if(showPerfStats) {
1113 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1114 perfList.push_back(perfBuf);
1115 }
1116
1117 // give CPU time to update other things to avoid apperance of hanging
1118 sleep(0);
1119 ::Shared::Platform::Window::handleEvent();
1120 SDL_PumpEvents();
1121
1122 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1123
1124 set<string> factions;
1125 for ( int i=0; i < gameSettings.getFactionCount(); ++i ) {
1126 factions.insert(gameSettings.getFactionTypeName(i));
1127 }
1128
1129 if(showPerfStats) {
1130 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1131 perfList.push_back(perfBuf);
1132 }
1133
1134 if((loadTypes & lgt_TechTree) == lgt_TechTree) {
1135 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1136
1137 //tech, load before map because of resources
1138 world.loadTech( config.getPathListForType(ptTechs,scenarioDir), techName,
1139 factions, &checksum,loadedFileList);
1140
1141 if(world.getTechTree() == NULL || world.getTechTree()->getNameUntranslated() == "") {
1142 char szBuf[8096]="";
1143 snprintf(szBuf,8096,"Line ref: %d, ERROR: Cannot find techtree: [%s]",__LINE__,techName.c_str());
1144
1145 throw megaglest_runtime_error(szBuf, true);
1146 }
1147 }
1148
1149 if(showPerfStats) {
1150 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1151 perfList.push_back(perfBuf);
1152 }
1153
1154 // give CPU time to update other things to avoid apperance of hanging
1155 sleep(0);
1156 ::Shared::Platform::Window::handleEvent();
1157 SDL_PumpEvents();
1158
1159 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1160
1161 //map
1162 if((loadTypes & lgt_Map) == lgt_Map) {
1163 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1164 world.loadMap(Config::getMapPath(mapName,scenarioDir), &checksum);
1165 }
1166
1167 if(showPerfStats) {
1168 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1169 perfList.push_back(perfBuf);
1170 }
1171
1172 // give CPU time to update other things to avoid apperance of hanging
1173 sleep(0);
1174 ::Shared::Platform::Window::handleEvent();
1175 SDL_PumpEvents();
1176
1177 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1178
1179 //scenario
1180 if((loadTypes & lgt_Scenario) == lgt_Scenario) {
1181 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1182 if(scenarioName.empty() == false) {
1183
1184 bool isTutorial = Scenario::isGameTutorial(gameSettings.getScenarioDir());
1185 //printf("Loading scenario gameSettings.getScenarioDir() [%s] scenarioName [%s] isTutorial: %d\n",gameSettings.getScenarioDir().c_str(),scenarioName.c_str(),isTutorial);
1186
1187 Lang::getInstance().loadScenarioStrings(gameSettings.getScenarioDir(), scenarioName, isTutorial);
1188
1189 //printf("In [%s::%s Line: %d] rootNode [%p][%s]\n",__FILE__,__FUNCTION__,__LINE__,loadGameNode,(loadGameNode != NULL ? loadGameNode->getName().c_str() : "none"));
1190 world.loadScenario(gameSettings.getScenarioDir(), &checksum, false,loadGameNode);
1191 }
1192 }
1193
1194 if(showPerfStats) {
1195 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1196 perfList.push_back(perfBuf);
1197 }
1198
1199 // give CPU time to update other things to avoid apperance of hanging
1200 sleep(0);
1201 SDL_PumpEvents();
1202
1203 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1204 //good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1205
1206 if(showPerfStats && chronoPerf.getMillis() >= 50) {
1207 for(unsigned int x = 0; x < perfList.size(); ++x) {
1208 printf("%s",perfList[x].c_str());
1209 }
1210 }
1211 }
1212
init()1213 void Game::init() {
1214 init(false);
1215 }
1216
init(bool initForPreviewOnly)1217 void Game::init(bool initForPreviewOnly) {
1218 bool showPerfStats = Config::getInstance().getBool("ShowPerfStats","false");
1219 Chrono chronoPerf;
1220 if(showPerfStats) chronoPerf.start();
1221 char perfBuf[8096]="";
1222 std::vector<string> perfList;
1223
1224 if(showPerfStats) {
1225 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1226 perfList.push_back(perfBuf);
1227 }
1228
1229 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] initForPreviewOnly = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,initForPreviewOnly);
1230
1231 Lang &lang= Lang::getInstance();
1232 Logger &logger= Logger::getInstance();
1233 CoreData &coreData= CoreData::getInstance();
1234 Renderer &renderer= Renderer::getInstance();
1235 Map *map= world.getMap();
1236 NetworkManager &networkManager= NetworkManager::getInstance();
1237
1238 GameSettings::playerDisconnectedText = "*" + lang.getString("AI") + "* ";
1239
1240 if(map == NULL) {
1241 throw megaglest_runtime_error("map == NULL");
1242 }
1243
1244 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1245
1246 if(initForPreviewOnly == false) {
1247 logger.setState(lang.getString("Initializing"));
1248
1249 //message box
1250 mainMessageBox.init(lang.getString("Yes"), lang.getString("No"));
1251 mainMessageBox.setEnabled(false);
1252
1253 //message box
1254 errorMessageBox.init(lang.getString("Ok"));
1255 errorMessageBox.setEnabled(false);
1256 errorMessageBox.setY(20);
1257
1258
1259 //init world, and place camera
1260 commander.init(&world);
1261
1262 // give CPU time to update other things to avoid apperance of hanging
1263 sleep(0);
1264 ::Shared::Platform::Window::handleEvent();
1265 SDL_PumpEvents();
1266 }
1267
1268 try {
1269 world.init(this, gameSettings.getDefaultUnits());
1270 }
1271 catch(const megaglest_runtime_error &ex) {
1272 string sErrBuf = "";
1273 if(ex.wantStackTrace() == true) {
1274 char szErrBuf[8096]="";
1275 snprintf(szErrBuf,8096,"In [%s::%s %d]",__FILE__,__FUNCTION__,__LINE__);
1276 sErrBuf = string(szErrBuf) + string("\nerror [") + string(ex.what()) + string("]\n");
1277 }
1278 else {
1279 sErrBuf = ex.what();
1280 }
1281 SystemFlags::OutputDebug(SystemFlags::debugError,sErrBuf.c_str());
1282 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,sErrBuf.c_str());
1283
1284 if(errorMessageBox.getEnabled() == false) {
1285 ErrorDisplayMessage(ex.what(),true);
1286 }
1287 }
1288 catch(const exception &ex) {
1289 char szErrBuf[8096]="";
1290 snprintf(szErrBuf,8096,"In [%s::%s %d]",__FILE__,__FUNCTION__,__LINE__);
1291 string sErrBuf = string(szErrBuf) + string("\nerror [") + string(ex.what()) + string("]\n");
1292 SystemFlags::OutputDebug(SystemFlags::debugError,sErrBuf.c_str());
1293 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,sErrBuf.c_str());
1294
1295 if(errorMessageBox.getEnabled() == false) {
1296 ErrorDisplayMessage(ex.what(),true);
1297 }
1298 }
1299
1300 if(showPerfStats) {
1301 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1302 perfList.push_back(perfBuf);
1303 }
1304
1305 if(loadGameNode != NULL) {
1306 //world.getMapPtr()->loadGame(loadGameNode,&world);
1307 }
1308
1309 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1310
1311 if(initForPreviewOnly == false) {
1312 // give CPU time to update other things to avoid apperance of hanging
1313 sleep(0);
1314 ::Shared::Platform::Window::handleEvent();
1315 SDL_PumpEvents();
1316
1317 gui.init(this);
1318
1319 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1320
1321 // give CPU time to update other things to avoid apperance of hanging
1322 sleep(0);
1323 //SDL_PumpEvents();
1324
1325 chatManager.init(&console, world.getThisTeamIndex());
1326 console.clearStoredLines();
1327 }
1328
1329 if(showPerfStats) {
1330 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1331 perfList.push_back(perfBuf);
1332 }
1333
1334 if(this->loadGameNode == NULL) {
1335 initCamera(map);
1336 }
1337 else {
1338 gui.loadGame(loadGameNode,&world);
1339
1340 if(inJoinGameLoading == true) {
1341 initCamera(map);
1342 }
1343 }
1344
1345 if(showPerfStats) {
1346 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1347 perfList.push_back(perfBuf);
1348 }
1349
1350 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1351
1352 NetworkRole role = nrIdle;
1353 if(initForPreviewOnly == false) {
1354 // give CPU time to update other things to avoid apperance of hanging
1355 sleep(0);
1356 ::Shared::Platform::Window::handleEvent();
1357 SDL_PumpEvents();
1358
1359 scriptManager.init(&world, &gameCamera,loadGameNode);
1360
1361 //good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1362
1363 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] creating AI's\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1364
1365 //create AIs
1366
1367 bool enableServerControlledAI = this->gameSettings.getEnableServerControlledAI();
1368 bool isNetworkGame = this->gameSettings.isNetworkGame();
1369 role = networkManager.getNetworkRole();
1370
1371 masterController.clearSlaves(true);
1372 deleteValues(aiInterfaces.begin(), aiInterfaces.end());
1373
1374 std::vector<SlaveThreadControllerInterface *> slaveThreadList;
1375 aiInterfaces.resize(world.getFactionCount());
1376 for(int i=0; i < world.getFactionCount(); ++i) {
1377 Faction *faction= world.getFaction(i);
1378
1379 //printf("Controltype = %d for index = %d\n",faction->getControlType(),i);
1380
1381 if(faction->getCpuControl(enableServerControlledAI,isNetworkGame,role) == true) {
1382 //printf("** Loading AI player for Controltype = %d for index = %d\n",faction->getControlType(),i);
1383
1384 aiInterfaces[i]= new AiInterface(*this, i, faction->getTeam());
1385 if(loadGameNode != NULL) {
1386 aiInterfaces[i]->loadGame(loadGameNode,faction);
1387 }
1388 char szBuf[8096]="";
1389 snprintf(szBuf,8096,Lang::getInstance().getString("LogScreenGameLoadingCreatingAIFaction","",true).c_str(),i);
1390 logger.add(szBuf, true);
1391
1392 slaveThreadList.push_back(aiInterfaces[i]->getWorkerThread());
1393 }
1394 else {
1395 aiInterfaces[i]= NULL;
1396 }
1397 }
1398 if(Config::getInstance().getBool("EnableNewThreadManager","false") == true) {
1399 masterController.setSlaves(slaveThreadList);
1400 }
1401
1402 if(showPerfStats) {
1403 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1404 perfList.push_back(perfBuf);
1405 }
1406
1407 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1408
1409 // give CPU time to update other things to avoid apperance of hanging
1410 sleep(0);
1411 ::Shared::Platform::Window::handleEvent();
1412 SDL_PumpEvents();
1413
1414 if(world.getFactionCount() == 1 && world.getFaction(0)->getPersonalityType() == fpt_Observer) {
1415 withRainEffect = false;
1416 }
1417
1418 if(withRainEffect) {
1419 //weather particle systems
1420 if(world.getTileset()->getWeather() == wRainy) {
1421 logger.add(Lang::getInstance().getString("LogScreenGameLoadingCreatingRainParticles","",true), true);
1422 weatherParticleSystem= new RainParticleSystem();
1423 weatherParticleSystem->setSpeed(12.f / GameConstants::updateFps);
1424 weatherParticleSystem->setPos(gameCamera.getPos());
1425 renderer.manageParticleSystem(weatherParticleSystem, rsGame);
1426 }
1427 else if(world.getTileset()->getWeather() == wSnowy) {
1428 logger.add(Lang::getInstance().getString("LogScreenGameLoadingCreatingSnowParticles","",true), true);
1429 weatherParticleSystem= new SnowParticleSystem(1200);
1430 weatherParticleSystem->setSpeed(1.5f / GameConstants::updateFps);
1431 weatherParticleSystem->setPos(gameCamera.getPos());
1432 weatherParticleSystem->setTexture(coreData.getSnowTexture());
1433 renderer.manageParticleSystem(weatherParticleSystem, rsGame);
1434 }
1435 }
1436 else if(world.getTileset()->getWeather() == wRainy) {
1437 world.getTileset()->setWeather(wSunny);
1438 }
1439
1440 renderer.manageDeferredParticleSystems();
1441 }
1442
1443 if(showPerfStats) {
1444 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1445 perfList.push_back(perfBuf);
1446 }
1447
1448 //init renderer state
1449 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Initializing renderer\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__);
1450 logger.add(Lang::getInstance().getString("LogScreenGameLoadingInitRenderer","",true), true);
1451
1452 //printf("Before renderer.initGame\n");
1453 renderer.initGame(this,this->getGameCameraPtr());
1454 //printf("After renderer.initGame\n");
1455
1456 if(showPerfStats) {
1457 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1458 perfList.push_back(perfBuf);
1459 }
1460
1461 for(int i=0; i < world.getFactionCount(); ++i) {
1462 Faction *faction= world.getFaction(i);
1463 if(faction != NULL) {
1464 faction->deletePixels();
1465 }
1466 }
1467
1468 if(showPerfStats) {
1469 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1470 perfList.push_back(perfBuf);
1471 }
1472
1473 if(initForPreviewOnly == false) {
1474 //good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1475
1476 // give CPU time to update other things to avoid apperance of hanging
1477 sleep(0);
1478 ::Shared::Platform::Window::handleEvent();
1479 SDL_PumpEvents();
1480
1481 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Waiting for network\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__);
1482 logger.add(Lang::getInstance().getString("LogScreenGameLoadingWaitForNetworkPlayers","",true), true);
1483 networkManager.getGameNetworkInterface()->waitUntilReady(&checksum);
1484
1485 //std::string worldLog = world.DumpWorldToLog(true);
1486
1487 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Starting music stream\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1488 logger.add(Lang::getInstance().getString("LogScreenGameLoadingStartingMusic","",true), true);
1489
1490 if(this->masterserverMode == false) {
1491 if(world.getThisFaction() == NULL) {
1492 throw megaglest_runtime_error("world.getThisFaction() == NULL");
1493 }
1494 if(world.getThisFaction()->getType() == NULL) {
1495 throw megaglest_runtime_error("world.getThisFaction()->getType() == NULL");
1496 }
1497 //if(world.getThisFaction()->getType()->getMusic() == NULL) {
1498 // throw megaglest_runtime_error("world.getThisFaction()->getType()->getMusic() == NULL");
1499 //}
1500 }
1501
1502 //sounds
1503 SoundRenderer &soundRenderer= SoundRenderer::getInstance();
1504 soundRenderer.stopAllSounds(fadeMusicMilliseconds);
1505 soundRenderer= SoundRenderer::getInstance();
1506
1507 Tileset *tileset= world.getTileset();
1508 AmbientSounds *ambientSounds= tileset->getAmbientSounds();
1509
1510 //rain
1511 if(tileset->getWeather() == wRainy && ambientSounds->isEnabledRain()) {
1512 logger.add(Lang::getInstance().getString("LogScreenGameLoadingStartingAmbient","",true), true);
1513 currentAmbientSound = ambientSounds->getRain();
1514 //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
1515 soundRenderer.playAmbient(currentAmbientSound);
1516 }
1517
1518 //snow
1519 if(tileset->getWeather() == wSnowy && ambientSounds->isEnabledSnow()) {
1520 logger.add(Lang::getInstance().getString("LogScreenGameLoadingStartingAmbient","",true), true);
1521 currentAmbientSound = ambientSounds->getSnow();
1522 //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
1523 soundRenderer.playAmbient(currentAmbientSound);
1524 }
1525
1526 if(this->masterserverMode == false) {
1527 StrSound *gameMusic= world.getThisFaction()->getType()->getMusic();
1528 soundRenderer.playMusic(gameMusic);
1529 }
1530
1531 logger.add(Lang::getInstance().getString("LogScreenGameLoadingLaunchGame","",true));
1532 }
1533
1534 if(showPerfStats) {
1535 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1536 perfList.push_back(perfBuf);
1537 }
1538
1539 //throw "test";
1540
1541 logger.setCancelLoadingEnabled(false);
1542
1543 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"================ STARTING GAME ================\n");
1544 if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled) SystemFlags::OutputDebug(SystemFlags::debugPathFinder,"================ STARTING GAME ================\n");
1545 setupPopupMenus(false);
1546
1547 for(int i=0; i < world.getFactionCount(); ++i) {
1548 Faction *faction= world.getFaction(i);
1549
1550 //printf("Check for team switch to observer i = %d, team = %d [%d]\n",i,faction->getTeam(),(GameConstants::maxPlayers -1 + fpt_Observer));
1551 if(faction != NULL && faction->getTeam() == GameConstants::maxPlayers -1 + fpt_Observer) {
1552 faction->setPersonalityType(fpt_Observer);
1553 world.getStats()->setPersonalityType(i, faction->getPersonalityType());
1554 }
1555 }
1556
1557 if(showPerfStats) {
1558 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1559 perfList.push_back(perfBuf);
1560 }
1561
1562 if(role == nrClient) {
1563 ClientInterface *clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
1564 if(clientInterface != NULL && clientInterface->getResumeInGameJoin() == true) {
1565
1566 //printf("Client sending resume message to server...\n");
1567
1568 clientInterface->sendResumeGameMessage();
1569 //this->initialResumeSpeedLoops = true;
1570 }
1571 }
1572
1573 printf("Game unique identifier is: %s\n",this->gameSettings.getGameUUID().c_str());
1574
1575 gameStarted = true;
1576
1577 if(this->masterserverMode == true) {
1578 world.getStats()->setIsMasterserverMode(true);
1579
1580 printf("New game has started...\n");
1581 }
1582
1583 if(isFlagType1BitEnabled(ft1_network_synch_checks_verbose) == true) {
1584 printf("*Note: Monitoring Network CRC VERBOSE synchronization...\n");
1585 }
1586 else if(isFlagType1BitEnabled(ft1_network_synch_checks) == true) {
1587 printf("*Note: Monitoring Network CRC NORMAL synchronization...\n");
1588 }
1589
1590 //NetworkRole role = networkManager.getNetworkRole();
1591 if(role == nrServer) {
1592 networkManager.initServerInterfaces(this);
1593 }
1594
1595 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ==== START GAME ==== getCurrentPixelByteCount() = " MG_SIZE_T_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderer.getCurrentPixelByteCount());
1596
1597 if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"=============================================\n");
1598 if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"==== START GAME ====\n");
1599 if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"=============================================\n");
1600 if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"Starting framecount: %d\n",world.getFrameCount());
1601
1602 if(showPerfStats && chronoPerf.getMillis() >= 50) {
1603 for(unsigned int x = 0; x < perfList.size(); ++x) {
1604 printf("%s",perfList[x].c_str());
1605 }
1606 }
1607 }
1608
initCamera(Map * map)1609 void Game::initCamera(Map *map){
1610 gameCamera.init(map->getW(), map->getH());
1611
1612 // camera default height calculation
1613 if(map->getCameraHeight()>0 && gameCamera.getCalculatedDefault()<map->getCameraHeight()){
1614 gameCamera.setCalculatedDefault(map->getCameraHeight());
1615 }
1616 else if(gameCamera.getCalculatedDefault()<map->getMaxMapHeight()+13.0f){
1617 gameCamera.setCalculatedDefault(map->getMaxMapHeight()+13.0f);
1618 }
1619
1620 if(world.getThisFaction() != NULL) {
1621 const Vec2i &v= map->getStartLocation(world.getThisFaction()->getStartLocationIndex());
1622 gameCamera.setPos(Vec2f(v.x, v.y+gameCamera.getCalculatedDefault()/2));
1623 }
1624 }
1625
1626 // ==================== update ====================
1627
reInitGUI()1628 void Game::reInitGUI() {
1629 gui.init(this);
1630 }
1631
setupPopupMenus(bool checkClientAdminOverrideOnly)1632 void Game::setupPopupMenus(bool checkClientAdminOverrideOnly) {
1633 Lang &lang= Lang::getInstance();
1634 NetworkManager &networkManager= NetworkManager::getInstance();
1635 NetworkRole role = networkManager.getNetworkRole();
1636 ClientInterface *clientInterface = NULL;
1637 ServerInterface *serverInterface = NULL;
1638
1639 bool allowAdminMenuItems = false;
1640 bool forceJoinInProgressUpdate = false;
1641 if(role == nrServer) {
1642 allowAdminMenuItems = true;
1643
1644 if(disconnectPlayerPopupMenuIndex == -1) {
1645 serverInterface = dynamic_cast<ServerInterface *>(networkManager.getServerInterface());
1646 if(serverInterface != NULL && checkClientAdminOverrideOnly == true) {
1647 for(int i = 0; i < world.getFactionCount(); ++i) {
1648 Faction *faction = world.getFaction(i);
1649
1650 MutexSafeWrapper safeMutex(serverInterface->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
1651 ConnectionSlot *slot = serverInterface->getSlot(faction->getStartLocationIndex(),false);
1652 if(slot != NULL && slot->getConnectHasHandshaked() == true &&
1653 slot->getCurrentFrameCount() <= 0) {
1654 //printf("Connected slot can be disconnected: %d\n",slot->getPlayerIndex());
1655
1656 forceJoinInProgressUpdate = true;
1657 break;
1658 }
1659 }
1660 }
1661 }
1662 }
1663 else if(role == nrClient) {
1664 clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
1665
1666 if(clientInterface != NULL &&
1667 (gameSettings.getMasterserver_admin() == clientInterface->getSessionKey() ||
1668 clientInterface->isMasterServerAdminOverride() == true)) {
1669 allowAdminMenuItems = true;
1670 }
1671 }
1672
1673 if(checkClientAdminOverrideOnly == false ||
1674 forceJoinInProgressUpdate == true ||
1675 (clientInterface != NULL &&
1676 (gameSettings.getMasterserver_admin() != clientInterface->getSessionKey() &&
1677 clientInterface->isMasterServerAdminOverride() == true))) {
1678 exitGamePopupMenuIndex = -1;
1679 joinTeamPopupMenuIndex = -1;
1680 pauseGamePopupMenuIndex = -1;
1681 saveGamePopupMenuIndex = -1;
1682 loadGamePopupMenuIndex = -1;
1683 keyboardSetupPopupMenuIndex = -1;
1684 disconnectPlayerPopupMenuIndex = -1;
1685
1686 if(checkClientAdminOverrideOnly == true && clientInterface != NULL) {
1687 gameSettings.setMasterserver_admin(clientInterface->getSessionKey());
1688 gameSettings.setMasterserver_admin_faction_index(clientInterface->getPlayerIndex());
1689 }
1690 //PopupMenu popupMenu;
1691 std::vector<string> menuItems;
1692 menuItems.push_back(" " + lang.getString("ExitGameMenu") + " ");
1693 exitGamePopupMenuIndex = (int)menuItems.size()-1;
1694
1695 if((gameSettings.getFlagTypes1() & ft1_allow_team_switching) == ft1_allow_team_switching &&
1696 world.getThisFaction() != NULL && world.getThisFaction()->getPersonalityType() != fpt_Observer) {
1697 menuItems.push_back(" " + lang.getString("JoinOtherTeam") + " ");
1698 joinTeamPopupMenuIndex = (int)menuItems.size()-1;
1699 }
1700
1701 if(allowAdminMenuItems == true){
1702 menuItems.push_back(" " + lang.getString("PauseResumeGame") + " ");
1703 pauseGamePopupMenuIndex= (int)menuItems.size() - 1;
1704
1705 if(gameSettings.isNetworkGame() == false || gameSettings.getScenario() != "") {
1706 menuItems.push_back(" " + lang.getString("SaveGame") + " ");
1707 saveGamePopupMenuIndex= (int)menuItems.size() - 1;
1708 }
1709
1710 if(gameSettings.isNetworkGame() == true) {
1711 menuItems.push_back(" " + lang.getString("DisconnectNetorkPlayer") + " ");
1712 disconnectPlayerPopupMenuIndex= (int)menuItems.size() - 1;
1713 }
1714 }
1715 menuItems.push_back(" " + lang.getString("KeyboardsetupL") + " ");
1716 keyboardSetupPopupMenuIndex = (int)menuItems.size()-1;
1717
1718 menuItems.push_back(" " + lang.getString("Cancel") + " ");
1719
1720 popupMenu.setW(100);
1721 popupMenu.setH(100);
1722 popupMenu.init(" " + lang.getString("GameMenuTitle") + " ",menuItems);
1723 popupMenu.setEnabled(false);
1724 popupMenu.setVisible(false);
1725
1726 popupMenuSwitchTeams.setEnabled(false);
1727 popupMenuSwitchTeams.setVisible(false);
1728
1729 popupMenuDisconnectPlayer.setEnabled(false);
1730 popupMenuDisconnectPlayer.setVisible(false);
1731 }
1732 }
1733
processNetworkSynchChecksIfRequired()1734 void Game::processNetworkSynchChecksIfRequired() {
1735 bool isNetworkGame = this->gameSettings.isNetworkGame();
1736 if (isNetworkGame == true && NetworkManager::getInstance().getGameNetworkInterface() != NULL) {
1737 GameSettings *settings = world.getGameSettingsPtr();
1738 if(settings != NULL) {
1739 bool calculateNetworkCRC = false;
1740
1741 if(isFlagType1BitEnabled(ft1_network_synch_checks) == true ||
1742 isFlagType1BitEnabled(ft1_network_synch_checks_verbose) == true) {
1743 calculateNetworkCRC = true;
1744 }
1745
1746 if(calculateNetworkCRC == true) {
1747 NetworkManager &networkManager = NetworkManager::getInstance();
1748 NetworkRole role = networkManager.getNetworkRole();
1749
1750 NetworkInterface *netIntf = networkManager.getGameNetworkInterface();
1751 for(int index = 0; index < GameConstants::maxPlayers; ++index) {
1752 if(index < world.getFactionCount()) {
1753 Faction *faction = world.getFaction(index);
1754 netIntf->setNetworkPlayerFactionCRC(index,faction->getCRC().getSum());
1755
1756 if(settings != NULL) {
1757 if(isFlagType1BitEnabled(ft1_network_synch_checks_verbose) == true) {
1758 faction->addCRC_DetailsForWorldFrame(world.getFrameCount(),role == nrServer);
1759 }
1760 else if(isFlagType1BitEnabled(ft1_network_synch_checks) == true &&
1761 world.getFrameCount() % 20 == 0) {
1762 faction->addCRC_DetailsForWorldFrame(world.getFrameCount(),role == nrServer);
1763 }
1764 }
1765 }
1766 else {
1767 netIntf->setNetworkPlayerFactionCRC(index,0);
1768 }
1769 }
1770 }
1771 }
1772 }
1773 }
1774
1775 //update
update()1776 void Game::update() {
1777 try {
1778 if(currentUIState != NULL) {
1779 currentUIState->update();
1780 }
1781
1782 bool showPerfStats = Config::getInstance().getBool("ShowPerfStats","false");
1783 Chrono chronoPerf;
1784 char perfBuf[8096]="";
1785 std::vector<string> perfList;
1786 if(showPerfStats) chronoPerf.start();
1787
1788 if(showPerfStats) {
1789 sprintf(perfBuf,"=============== FRAME: %d In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",world.getFrameCount(),extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1790 perfList.push_back(perfBuf);
1791 }
1792
1793 Chrono chronoGamePerformanceCounts;
1794 Chrono chrono;
1795 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
1796
1797 // a) Updates non dependent on speed
1798
1799 // set game stats for host
1800 NetworkManager &networkManager = NetworkManager::getInstance();
1801 NetworkRole role = networkManager.getNetworkRole();
1802 if(role == nrServer) {
1803 ServerInterface *server = NetworkManager::getInstance().getServerInterface(false);
1804 if(server != NULL) {
1805 server->setGameStats(world.getStats());
1806 }
1807 }
1808
1809 bool pendingQuitError = (quitPendingIndicator == true ||
1810 (NetworkManager::getInstance().getGameNetworkInterface() != NULL &&
1811 NetworkManager::getInstance().getGameNetworkInterface()->getQuit()));
1812
1813 if(pendingQuitError == true &&
1814 (this->masterserverMode == true ||
1815 (mainMessageBox.getEnabled() == false && errorMessageBox.getEnabled() == false))) {
1816 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1817
1818 quitTriggeredIndicator = true;
1819 return;
1820 }
1821
1822 if(this->masterserverMode == false) {
1823 if(world.getFactionCount() > 0 && world.getThisFaction()->getFirstSwitchTeamVote() != NULL) {
1824 const SwitchTeamVote *vote = world.getThisFaction()->getFirstSwitchTeamVote();
1825 GameSettings *settings = world.getGameSettingsPtr();
1826
1827 Lang &lang= Lang::getInstance();
1828
1829 char szBuf[8096]="";
1830 if(lang.hasString("AllowPlayerJoinTeam") == true) {
1831 snprintf(szBuf,8096,lang.getString("AllowPlayerJoinTeam").c_str(),settings->getNetworkPlayerName(vote->factionIndex).c_str(),vote->oldTeam,vote->newTeam);
1832 }
1833 else {
1834 snprintf(szBuf,8096,"Allow player [%s] to join your team\n(changing from team# %d to team# %d)?",settings->getNetworkPlayerName(vote->factionIndex).c_str(),vote->oldTeam,vote->newTeam);
1835 }
1836
1837 switchTeamConfirmMessageBox.setText(szBuf);
1838 switchTeamConfirmMessageBox.init(lang.getString("Yes"), lang.getString("No"));
1839 switchTeamConfirmMessageBox.setEnabled(true);
1840
1841 world.getThisFactionPtr()->setCurrentSwitchTeamVoteFactionIndex(vote->factionIndex);
1842 }
1843 }
1844
1845 //misc
1846 updateFps++;
1847 mouse2d= (mouse2d+1) % Renderer::maxMouse2dAnim;
1848
1849 //console
1850 console.update();
1851
1852 // b) Updates depandant on speed
1853 int updateLoops= getUpdateLoops();
1854
1855 // Temp speed boost when player first joins an in progress game
1856 if(this->initialResumeSpeedLoops == true) {
1857 printf("Resume In Progress Game: %d\n",__LINE__);
1858
1859 this->initialResumeSpeedLoops = false;
1860 //updateLoops = 80;
1861 }
1862
1863 chronoGamePerformanceCounts.start();
1864 bool enableServerControlledAI = this->gameSettings.getEnableServerControlledAI();
1865
1866 if(role == nrClient && updateLoops == 1 && world.getFrameCount() >= (gameSettings.getNetworkFramePeriod() * 2) ) {
1867 ClientInterface *clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
1868 if(clientInterface != NULL) {
1869 uint64 lastNetworkFrameFromServer = clientInterface->getCachedLastPendingFrameCount();
1870
1871 /////////////////////////////////
1872 // TTTT new attempt to make things smoother:
1873 ///////////////
1874
1875 ////////////////////////////////////////////
1876 //get stats of received/waiting for packages
1877 ////////////////////////////////////////////
1878 // calculate current receive Index slot:
1879 int index = ((world.getFrameCount()
1880 - (world.getFrameCount()
1881 % gameSettings.getNetworkFramePeriod()))
1882 / gameSettings.getNetworkFramePeriod())
1883 % GameConstants::networkSmoothInterval;
1884
1885 // clean the next frame slot
1886 receivedTooEarlyInFrames[(index+1)%GameConstants::networkSmoothInterval]=-1;
1887 framesNeededToWaitForServerMessage[(index+1)%GameConstants::networkSmoothInterval]=-1;
1888
1889 if(receivedTooEarlyInFrames[index]==-1){
1890 // we need to check if we already received something for next frame
1891 if(lastNetworkFrameFromServer > 0 && lastNetworkFrameFromServer > (uint64)world.getFrameCount()) {
1892 receivedTooEarlyInFrames[index]= lastNetworkFrameFromServer-world.getFrameCount();
1893 }
1894 }
1895 if(framesNeededToWaitForServerMessage[index]==-1){
1896 // calc time waiting for message in milliseconds to frames
1897 int64 timeClientWaitedForLastMessage=clientInterface->getTimeClientWaitedForLastMessage();
1898 if(timeClientWaitedForLastMessage>0){
1899 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("world.getFrameCount():%d index %d Client waited:%d ms\n",world.getFrameCount(),index,(int)timeClientWaitedForLastMessage);
1900 framesNeededToWaitForServerMessage[index]=timeClientWaitedForLastMessage*GameConstants::updateFps/1000;
1901 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("ClienttimeClientWaitedForLastMessage:%d ms which is %d frames \n",(int)timeClientWaitedForLastMessage,framesNeededToWaitForServerMessage[index]);
1902 }
1903 else {
1904 framesNeededToWaitForServerMessage[index]=0;
1905 }
1906 }
1907
1908 ////////////////////////////////////////////
1909 //use the recorded stats of received/waiting for packages
1910 ////////////////////////////////////////////
1911 //lets see if the client is in front and had to wait for messages ...
1912
1913 //lets see if all last recorded frames where received too early
1914 int minimum=0;
1915 int allowedMaxFallback=5;
1916 int countOfMessagesReceivedTooEarly=0;
1917 int countOfMessagesReceivedTooLate=0;
1918 int sumOfTooLateFrames=0;
1919 bool cleanupStats=false;
1920
1921 for( int i=0;i<GameConstants::networkSmoothInterval;i++){
1922 if(receivedTooEarlyInFrames[i]>allowedMaxFallback){
1923 countOfMessagesReceivedTooEarly++;
1924 if ( minimum == 0 || minimum > receivedTooEarlyInFrames[i] ){
1925 minimum=receivedTooEarlyInFrames[i];
1926 }
1927 }
1928 if(framesNeededToWaitForServerMessage[i]>0){
1929 countOfMessagesReceivedTooLate++;
1930 sumOfTooLateFrames+=framesNeededToWaitForServerMessage[i];
1931 }
1932 }
1933
1934 if( countOfMessagesReceivedTooEarly==GameConstants::networkSmoothInterval-1 ) // -1 because slot for next frame is already initialized
1935 {// all packages where too early
1936 // we catch up the minimum-catchupInterval of what we recorded
1937 framesToCatchUpAsClient=minimum-allowedMaxFallback;
1938 framesToSlowDownAsClient=0;
1939 cleanupStats=true;
1940 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Worldframe %d : Client will speed up: %d frames\n",world.getFrameCount(),framesToCatchUpAsClient);
1941 }
1942 else if(countOfMessagesReceivedTooLate>3){
1943 framesToSlowDownAsClient=sumOfTooLateFrames/countOfMessagesReceivedTooLate;
1944 framesToCatchUpAsClient=0;
1945 cleanupStats=true;
1946 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Worldframe %d : Client will slow down: %d frames\n",world.getFrameCount(),framesToSlowDownAsClient);
1947 }
1948
1949 if(cleanupStats==true) {
1950 // Once we decided to use the stats to do some correction, we reset/cleanup our recorded stats
1951 for( int i=0;i<GameConstants::networkSmoothInterval;i++){
1952 receivedTooEarlyInFrames[i]=-1;
1953 framesNeededToWaitForServerMessage[i]=-1;
1954 }
1955 }
1956 }
1957 }
1958 // if game is paused don't try to catch up
1959 if(updateLoops > 0) {
1960 // we catch up a bit smoother with updateLoops = 2
1961 if(framesToCatchUpAsClient>0)
1962 {
1963 updateLoops = 2;
1964 framesToCatchUpAsClient=framesToCatchUpAsClient-1;
1965 }
1966 if(framesToSlowDownAsClient>0)
1967 {// slowdown still the hard way.
1968 updateLoops = 0;
1969 framesToSlowDownAsClient=framesToSlowDownAsClient-1;
1970 }
1971 }
1972
1973 addPerformanceCount("CalculateNetworkUpdateLoops",chronoGamePerformanceCounts.getMillis());
1974
1975 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
1976 if(showPerfStats) {
1977 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1978 perfList.push_back(perfBuf);
1979 }
1980
1981 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [before ReplaceDisconnectedNetworkPlayersWithAI]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
1982 if(showPerfStats) {
1983 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
1984 perfList.push_back(perfBuf);
1985 }
1986
1987 // Check to see if we are playing a network game and if any players
1988 // have disconnected?
1989 bool isNetworkGame = this->gameSettings.isNetworkGame();
1990
1991 chronoGamePerformanceCounts.start();
1992
1993 ReplaceDisconnectedNetworkPlayersWithAI(isNetworkGame, role);
1994
1995 addPerformanceCount("ReplaceDisconnectedNetworkPlayersWithAI",chronoGamePerformanceCounts.getMillis());
1996
1997 setupPopupMenus(true);
1998
1999 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after ReplaceDisconnectedNetworkPlayersWithAI]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
2000 if(showPerfStats) {
2001 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2002 perfList.push_back(perfBuf);
2003 }
2004
2005 if(updateLoops > 0) {
2006 // update the frame based timer in the stats with at least one step
2007 world.getStats()->addFramesToCalculatePlaytime();
2008
2009 //update
2010 Chrono chronoReplay;
2011 int64 lastReplaySecond = -1;
2012 int replayCommandsPlayed = 0;
2013 int replayTotal = commander.getReplayCommandListForFrameCount();
2014 if(replayTotal > 0) {
2015 chronoReplay.start();
2016 }
2017
2018 do {
2019 if(replayTotal > 0) {
2020 replayCommandsPlayed = (replayTotal - commander.getReplayCommandListForFrameCount());
2021 }
2022 for(int i = 0; i < updateLoops; ++i) {
2023 //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
2024 if(showPerfStats) {
2025 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2026 perfList.push_back(perfBuf);
2027 }
2028
2029 //AiInterface
2030 if(commander.hasReplayCommandListForFrame() == false) {
2031 chronoGamePerformanceCounts.start();
2032
2033 processNetworkSynchChecksIfRequired();
2034
2035 addPerformanceCount("CalculateNetworkCRCSynchChecks",chronoGamePerformanceCounts.getMillis());
2036
2037 const bool newThreadManager = Config::getInstance().getBool("EnableNewThreadManager","false");
2038 if(newThreadManager == true) {
2039 int currentFrameCount = world.getFrameCount();
2040 masterController.signalSlaves(¤tFrameCount);
2041 //bool slavesCompleted = masterController.waitTillSlavesTrigger(20000);
2042 masterController.waitTillSlavesTrigger(20000);
2043 }
2044 else {
2045 // Signal the faction threads to do any pre-processing
2046 chronoGamePerformanceCounts.start();
2047
2048 bool hasAIPlayer = false;
2049 for(int j = 0; j < world.getFactionCount(); ++j) {
2050 Faction *faction = world.getFaction(j);
2051
2052 //printf("Faction Index = %d enableServerControlledAI = %d, isNetworkGame = %d, role = %d isCPU player = %d scriptManager.getPlayerModifiers(j)->getAiEnabled() = %d\n",j,enableServerControlledAI,isNetworkGame,role,faction->getCpuControl(enableServerControlledAI,isNetworkGame,role),scriptManager.getPlayerModifiers(j)->getAiEnabled());
2053
2054 if( faction->getCpuControl(enableServerControlledAI,isNetworkGame,role) == true &&
2055 scriptManager.getPlayerModifiers(j)->getAiEnabled() == true) {
2056
2057 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] [i = %d] faction = %d, factionCount = %d, took msecs: %lld [before AI updates]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,j,world.getFactionCount(),chrono.getMillis());
2058 aiInterfaces[j]->signalWorkerThread(world.getFrameCount());
2059 hasAIPlayer = true;
2060 }
2061 }
2062
2063 if(showPerfStats) {
2064 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2065 perfList.push_back(perfBuf);
2066 }
2067
2068 if(hasAIPlayer == true) {
2069 //sleep(0);
2070
2071 Chrono chronoAI;
2072 chronoAI.start();
2073
2074 const int MAX_FACTION_THREAD_WAIT_MILLISECONDS = 20000;
2075 for(;chronoAI.getMillis() < MAX_FACTION_THREAD_WAIT_MILLISECONDS;) {
2076 bool workThreadsFinished = true;
2077 for(int j = 0; j < world.getFactionCount(); ++j) {
2078 Faction *faction = world.getFaction(j);
2079 if(faction == NULL) {
2080 throw megaglest_runtime_error("faction == NULL");
2081 }
2082 if( faction->getCpuControl(enableServerControlledAI,isNetworkGame,role) == true &&
2083 scriptManager.getPlayerModifiers(j)->getAiEnabled() == true) {
2084 if(aiInterfaces[j]->isWorkerThreadSignalCompleted(world.getFrameCount()) == false) {
2085 workThreadsFinished = false;
2086 break;
2087 }
2088 }
2089 }
2090 if(workThreadsFinished == false) {
2091 //sleep(0);
2092 }
2093 else {
2094 break;
2095 }
2096 }
2097 }
2098
2099 addPerformanceCount("ProcessAIWorkerThreads",chronoGamePerformanceCounts.getMillis());
2100 }
2101
2102 if(showPerfStats) {
2103 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2104 perfList.push_back(perfBuf);
2105 }
2106
2107 }
2108 else {
2109 // Simply show a progress message while replaying commands
2110 if(lastReplaySecond < chronoReplay.getSeconds()) {
2111 lastReplaySecond = chronoReplay.getSeconds();
2112 Renderer &renderer= Renderer::getInstance();
2113 renderer.clearBuffers();
2114 renderer.clearZBuffer();
2115 renderer.reset2d();
2116
2117 char szBuf[8096]="";
2118 snprintf(szBuf,8096,"Please wait, loading game with replay [%d / %d]...",replayCommandsPlayed,replayTotal);
2119 string text = szBuf;
2120 if(Renderer::renderText3DEnabled) {
2121 Font3D *font = CoreData::getInstance().getMenuFontBig3D();
2122 const Metrics &metrics= Metrics::getInstance();
2123 int w= metrics.getVirtualW();
2124 int renderX = (w / 2) - (font->getMetrics()->getTextWidth(text) / 2);
2125 int h= metrics.getVirtualH();
2126 int renderY = (h / 2) + (font->getMetrics()->getHeight(text) / 2);
2127
2128 renderer.renderText3D(
2129 text, font,
2130 Vec3f(1.f, 1.f, 0.f),
2131 renderX, renderY, false);
2132 }
2133 else {
2134 Font2D *font = CoreData::getInstance().getMenuFontBig();
2135 const Metrics &metrics= Metrics::getInstance();
2136 int w= metrics.getVirtualW();
2137 int renderX = (w / 2);
2138 int h= metrics.getVirtualH();
2139 int renderY = (h / 2);
2140
2141 renderer.renderText(
2142 text, font,
2143 Vec3f(1.f, 1.f, 0.f),
2144 renderX, renderY, true);
2145 }
2146
2147 renderer.swapBuffers();
2148 }
2149 }
2150
2151 if(showPerfStats) {
2152 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2153 perfList.push_back(perfBuf);
2154 }
2155
2156 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [AI updates]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
2157 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
2158
2159 //World
2160 chronoGamePerformanceCounts.start();
2161
2162 if(pendingQuitError == false) world.update();
2163
2164 addPerformanceCount("ProcessWorldUpdate",chronoGamePerformanceCounts.getMillis());
2165
2166 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [world update i = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),i);
2167 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
2168
2169 if(showPerfStats) {
2170 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2171 perfList.push_back(perfBuf);
2172 }
2173
2174 if(currentCameraFollowUnit != NULL) {
2175 Vec3f c=currentCameraFollowUnit->getCurrMidHeightVector();
2176 int rotation=currentCameraFollowUnit->getRotation();
2177 float angle=rotation+180;
2178
2179 c.z=c.z+4*std::cos(degToRad(angle));
2180 c.x=c.x+4*std::sin(degToRad(angle));
2181
2182 c.y=c.y+currentCameraFollowUnit->getType()->getHeight()/2.f+2.0f;
2183
2184 getGameCameraPtr()->setPos(c);
2185
2186 rotation=(540-rotation)%360;
2187 getGameCameraPtr()->rotateToVH(18.0f,rotation);
2188
2189 if(currentCameraFollowUnit->isAlive()==false){
2190 currentCameraFollowUnit=NULL;
2191 getGameCameraPtr()->setState(GameCamera::sGame);
2192 }
2193 }
2194
2195 if(showPerfStats) {
2196 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2197 perfList.push_back(perfBuf);
2198 }
2199
2200 // Commander
2201 chronoGamePerformanceCounts.start();
2202
2203 if(pendingQuitError == false) {
2204 commander.signalNetworkUpdate(this);
2205 }
2206
2207 addPerformanceCount("ProcessNetworkUpdate",chronoGamePerformanceCounts.getMillis());
2208
2209 if(showPerfStats) {
2210 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2211 perfList.push_back(perfBuf);
2212 }
2213
2214 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [commander updateNetwork i = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),i);
2215 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
2216
2217 //Gui
2218 chronoGamePerformanceCounts.start();
2219
2220 gui.update();
2221
2222 addPerformanceCount("ProcessGUIUpdate",chronoGamePerformanceCounts.getMillis());
2223
2224 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [gui updating i = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),i);
2225 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
2226
2227 if(showPerfStats) {
2228 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2229 perfList.push_back(perfBuf);
2230 }
2231
2232 //Particle systems
2233 if(weatherParticleSystem != NULL) {
2234 weatherParticleSystem->setPos(gameCamera.getPos());
2235 }
2236
2237 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [weather particle updating i = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),i);
2238 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
2239
2240 if(showPerfStats) {
2241 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2242 perfList.push_back(perfBuf);
2243 }
2244
2245 Renderer &renderer= Renderer::getInstance();
2246
2247 chronoGamePerformanceCounts.start();
2248
2249 renderer.updateParticleManager(rsGame,avgRenderFps);
2250
2251 addPerformanceCount("ProcessParticleManager",chronoGamePerformanceCounts.getMillis());
2252
2253 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [particle manager updating i = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),i);
2254 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
2255
2256 if(showPerfStats) {
2257 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2258 perfList.push_back(perfBuf);
2259 }
2260
2261 //good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
2262 }
2263 }
2264 while (commander.hasReplayCommandListForFrame() == true);
2265 }
2266 //else if(role == nrClient) {
2267 else {
2268 if(pendingQuitError == false) {
2269 commander.signalNetworkUpdate(this);
2270 }
2271
2272 if(playingStaticVideo == true) {
2273 if(videoPlayer->isPlaying() == false) {
2274 playingStaticVideo = false;
2275 tryPauseToggle(false);
2276 }
2277 }
2278 }
2279
2280 if(showPerfStats) {
2281 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2282 perfList.push_back(perfBuf);
2283 }
2284
2285 chronoGamePerformanceCounts.start();
2286
2287 //call the chat manager
2288 chatManager.updateNetwork();
2289 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [chatManager.updateNetwork]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
2290 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
2291
2292 if(showPerfStats) {
2293 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2294 perfList.push_back(perfBuf);
2295 }
2296
2297 updateNetworkMarkedCells();
2298 updateNetworkUnMarkedCells();
2299 updateNetworkHighligtedCells();
2300
2301 if(showPerfStats) {
2302 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2303 perfList.push_back(perfBuf);
2304 }
2305
2306 //check for quiting status
2307 if(NetworkManager::getInstance().getGameNetworkInterface() != NULL &&
2308 NetworkManager::getInstance().getGameNetworkInterface()->getQuit() &&
2309 mainMessageBox.getEnabled() == false &&
2310 errorMessageBox.getEnabled() == false) {
2311 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
2312 quitTriggeredIndicator = true;
2313 return;
2314 }
2315
2316 if(showPerfStats) {
2317 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2318 perfList.push_back(perfBuf);
2319 }
2320
2321 addPerformanceCount("ProcessMiscNetwork",chronoGamePerformanceCounts.getMillis());
2322
2323 // START - Handle joining in progress games
2324 if(role == nrServer) {
2325
2326 if(this->networkPauseGameForLaggedClientsRequested == true) {
2327 this->networkPauseGameForLaggedClientsRequested = false;
2328
2329 if(getPaused() == false) {
2330
2331 printf("[CMDR] Pausing game for lagging client(s), current world frame [%d]\n",world.getFrameCount());
2332 commander.tryPauseGame(false,false);
2333 }
2334 }
2335 else if(this->networkResumeGameForLaggedClientsRequested == true) {
2336 this->networkResumeGameForLaggedClientsRequested = false;
2337
2338 if(getPaused() == true) {
2339
2340 printf("[CMDR] Resuming game after Pause for lagging client(s), current world frame [%d]\n",world.getFrameCount());
2341 commander.tryResumeGame(false,false);
2342 }
2343 }
2344
2345 ServerInterface *server = NetworkManager::getInstance().getServerInterface();
2346 if(server->getPauseForInGameConnection() == true) {
2347
2348 bool clientNeedsGameSetup = false;
2349 for(int i = 0; i < world.getFactionCount(); ++i) {
2350 Faction *faction = world.getFaction(i);
2351
2352 MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
2353 ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
2354 if(slot != NULL && slot->getPauseForInGameConnection() == true) {
2355 clientNeedsGameSetup = true;
2356 break;
2357 }
2358 }
2359
2360 if(pausedForJoinGame == false || clientNeedsGameSetup == true) {
2361 //printf("================= Switching player pausing game\n");
2362
2363 for(int i = 0; i < world.getFactionCount(); ++i) {
2364 Faction *faction = world.getFaction(i);
2365
2366 //printf("Switching player check %d from: %d connected: %d, startindex = %d, connected #2: %d\n",i,faction->getControlType(),server->isClientConnected(faction->getStartLocationIndex()),faction->getStartLocationIndex(),server->isClientConnected(i));
2367 //printf("Slot: %d faction name: %s\n",i,faction->getType()->getName().c_str());
2368
2369 if( faction->getControlType() != ctNetwork &&
2370 faction->getControlType() != ctHuman &&
2371 server->isClientConnected(faction->getStartLocationIndex()) == true) {
2372
2373 //printf("Switching player %d from: %d to %d\n",i,faction->getControlType(),ctNetwork);
2374 //printf("Slot: %d faction name: %s GS faction: %s\n",i,faction->getType()->getName().c_str(),server->gameSettings.getFactionTypeName(i).c_str());
2375
2376 server->gameSettings.setFactionControl(i,ctNetwork);
2377
2378 MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
2379 ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
2380 server->gameSettings.setNetworkPlayerName(i,slot->getName());
2381 server->gameSettings.setNetworkPlayerUUID(i,slot->getUUID());
2382 server->gameSettings.setNetworkPlayerPlatform(i,slot->getPlatform());
2383 safeMutex.ReleaseLock();
2384 server->gameSettings.setNetworkPlayerStatuses(i,npst_None);
2385
2386 this->gameSettings.setFactionControl(i,ctNetwork);
2387 this->gameSettings.setNetworkPlayerName(i,server->gameSettings.getNetworkPlayerName(i));
2388 this->gameSettings.setNetworkPlayerUUID(i,server->gameSettings.getNetworkPlayerUUID(i));
2389 this->gameSettings.setNetworkPlayerPlatform(i,server->gameSettings.getNetworkPlayerPlatform(i));
2390 this->gameSettings.setNetworkPlayerStatuses(i,npst_None);
2391 }
2392 }
2393 //printf("#1 Data synch: lmap %u ltile: %d ltech: %u\n",gameSettings.getMapCRC(),gameSettings.getTilesetCRC(),gameSettings.getTechCRC());
2394 //printf("#2 Data synch: lmap %u ltile: %d ltech: %u\n",server->gameSettings.getMapCRC(),server->gameSettings.getTilesetCRC(),server->gameSettings.getTechCRC());
2395 server->broadcastGameSetup(&server->gameSettings,true);
2396 }
2397
2398 for(int i = 0; i < world.getFactionCount(); ++i) {
2399 Faction *faction = world.getFaction(i);
2400 MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
2401 ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
2402 if(slot != NULL && slot->getPauseForInGameConnection() == true) {
2403 slot->setPauseForInGameConnection(false);
2404 }
2405 }
2406 }
2407 else if(server->getStartInGameConnectionLaunch() == true) {
2408 //printf("^^^ getStartInGameConnectionLaunch triggered!\n");
2409
2410 //server->setStartInGameConnectionLaunch(false);
2411
2412 //this->speed = 1;
2413
2414 //Lang &lang= Lang::getInstance();
2415 bool pauseAndSaveGameForNewClient = false;
2416 for(int i = 0; i < world.getFactionCount(); ++i) {
2417 Faction *faction = world.getFaction(i);
2418
2419 MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
2420 ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
2421
2422 if(slot != NULL && slot->getStartInGameConnectionLaunch() == true) {
2423 //slot->setStartInGameConnectionLaunch(false);
2424 pauseAndSaveGameForNewClient = true;
2425 }
2426 if(slot != NULL && slot->getJoinGameInProgress() == true) {
2427 //printf("$$$ signalling client to start game [deleting AI player] factionIndex: %d slot: %d startlocation: %d!\n",i,slot->getPlayerIndex(),faction->getStartLocationIndex());
2428 safeMutex.ReleaseLock();
2429
2430 this->gameSettings.setFactionControl(i,ctNetwork);
2431 this->gameSettings.setNetworkPlayerName(i,server->gameSettings.getNetworkPlayerName(i));
2432 this->gameSettings.setNetworkPlayerUUID(i,server->gameSettings.getNetworkPlayerUUID(i));
2433 this->gameSettings.setNetworkPlayerPlatform(i,server->gameSettings.getNetworkPlayerPlatform(i));
2434
2435 if(this->gameSettings.getNetworkPlayerStatuses(i) == npst_Disconnected) {
2436 this->gameSettings.setNetworkPlayerStatuses(i,npst_None);
2437 }
2438
2439 //printf("START Purging AI player for index: %d\n",i);
2440 masterController.clearSlaves(true);
2441 delete aiInterfaces[i];
2442 aiInterfaces[i] = NULL;
2443 //printf("END Purging AI player for index: %d\n",i);
2444
2445 Faction *faction = world.getFaction(i);
2446 faction->setControlType(ctNetwork);
2447 //pauseAndSaveGameForNewClient = true;
2448 }
2449 else if((slot == NULL || slot->isConnected() == false) &&
2450 this->gameSettings.getFactionControl(i) == ctNetwork &&
2451 aiInterfaces[i] == NULL) {
2452
2453 safeMutex.ReleaseLock();
2454 faction->setFactionDisconnectHandled(false);
2455 //this->gameSettings.setNetworkPlayerName(i,lang.getString("AI") + intToStr(i+1));
2456 //server->gameSettings.setNetworkPlayerName(i,lang.getString("AI") + intToStr(i+1));
2457 }
2458 else {
2459 safeMutex.ReleaseLock();
2460 }
2461 }
2462
2463 if(pauseAndSaveGameForNewClient == true && pausedForJoinGame == false &&
2464 pauseRequestSent == false) {
2465 //printf("Pausing game for join in progress game...\n");
2466
2467 commander.tryPauseGame(true,true);
2468 pauseRequestSent = true;
2469 return;
2470 }
2471 }
2472 //else if(server->getPauseForInGameConnection() == true && paused == true &&
2473 if(pausedForJoinGame == true) {
2474 if(pauseStateChanged == true) {
2475 pauseStateChanged = false;
2476 }
2477
2478 if(server->getUnPauseForInGameConnection() == true) {
2479 //printf("^^^ getUnPauseForInGameConnection triggered!\n");
2480
2481 for(int i = 0; i < world.getFactionCount(); ++i) {
2482 Faction *faction = world.getFaction(i);
2483
2484 MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
2485 ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
2486 if(slot != NULL && slot->getUnPauseForInGameConnection() == true) {
2487 slot->setUnPauseForInGameConnection(false);
2488 faction->setFactionDisconnectHandled(false);
2489 }
2490 }
2491 //printf("Resuming game for join in progress game resumeRequestSent: %d...\n",resumeRequestSent);
2492
2493 if(pausedBeforeJoinGame == false && resumeRequestSent == false) {
2494 commander.tryResumeGame(true,true);
2495 resumeRequestSent = true;
2496 }
2497 }
2498 else if(server->getStartInGameConnectionLaunch() == true) {
2499 bool saveNetworkGame = false;
2500
2501 ServerInterface *server = NetworkManager::getInstance().getServerInterface();
2502 for(int i = 0; i < world.getFactionCount(); ++i) {
2503 Faction *faction = world.getFaction(i);
2504
2505 MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
2506 ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
2507 if(slot != NULL && slot->getJoinGameInProgress() == true &&
2508 slot->getStartInGameConnectionLaunch() == true &&
2509 slot->getSentSavedGameInfo() == false) {
2510 slot->setStartInGameConnectionLaunch(false);
2511
2512 saveNetworkGame = true;
2513 break;
2514 }
2515 }
2516
2517 if(saveNetworkGame == true) {
2518 //printf("Saved network game to disk\n");
2519
2520 string file = this->saveGame(GameConstants::saveNetworkGameFileServer,"temp/");
2521
2522 string saveGameFilePath = "temp/";
2523 string saveGameFileCompressed = saveGameFilePath + string(GameConstants::saveNetworkGameFileServerCompressed);
2524 if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
2525 saveGameFilePath = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + saveGameFilePath;
2526 saveGameFileCompressed = saveGameFilePath + string(GameConstants::saveNetworkGameFileServerCompressed);
2527 }
2528 else {
2529 string userData = Config::getInstance().getString("UserData_Root","");
2530 if(userData != "") {
2531 endPathWithSlash(userData);
2532 }
2533 saveGameFilePath = userData + saveGameFilePath;
2534 saveGameFileCompressed = saveGameFilePath + string(GameConstants::saveNetworkGameFileServerCompressed);
2535 }
2536
2537 bool compressed_result = compressFileToZIPFile(
2538 file, saveGameFileCompressed);
2539 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Saved game [%s] compressed to [%s] returned: %d\n",file.c_str(),saveGameFileCompressed.c_str(), compressed_result);
2540
2541 char szBuf[8096]="";
2542 Lang &lang= Lang::getInstance();
2543 snprintf(szBuf,8096,lang.getString("GameSaved","",true).c_str(),file.c_str());
2544 console.addLine(szBuf);
2545
2546 for(int i = 0; i < world.getFactionCount(); ++i) {
2547 Faction *faction = world.getFaction(i);
2548
2549 MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
2550 ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
2551 if(slot != NULL && slot->getJoinGameInProgress() == true &&
2552 slot->getSentSavedGameInfo() == false) {
2553
2554 safeMutex.ReleaseLock();
2555 NetworkMessageReady networkMessageReady(0);
2556 slot->sendMessage(&networkMessageReady);
2557
2558 slot = server->getSlot(faction->getStartLocationIndex(),false);
2559 if(slot != NULL) {
2560 slot->setSentSavedGameInfo(true);
2561 }
2562 }
2563 }
2564 }
2565 }
2566 }
2567 //else {
2568 // handle setting changes from clients
2569 Map *map= world.getMap();
2570 //printf("switchSetupRequests != NULL\n");
2571
2572 bool switchRequested = switchSetupForSlots(server, 0, map->getMaxPlayers(), false);
2573 switchRequested = switchRequested || switchSetupForSlots(server, map->getMaxPlayers(), GameConstants::maxPlayers, true);
2574
2575 if(switchRequested == true) {
2576 //printf("Send new game setup from switch: %d\n",switchRequested);
2577
2578 //for(int i= 0; i < gameSettings.getFactionCount(); ++i) {
2579 //printf("#1 Faction Index: %d control: %d startlocation: %d\n",i,gameSettings.getFactionControl(i),gameSettings.getStartLocationIndex(i));
2580
2581 //printf("#2 Faction Index: %d control: %d startlocation: %d\n",i,server->gameSettings.getFactionControl(i),server->gameSettings.getStartLocationIndex(i));
2582 //}
2583
2584 server->broadcastGameSetup(&server->gameSettings,true);
2585 }
2586 //}
2587
2588 // Make the server wait a bit for clients to start.
2589 if(pausedForJoinGame == false && resumeRequestSent == true) {
2590 resumeRequestSent = false;
2591 //sleep(500);
2592 }
2593 }
2594 // END - Handle joining in progress games
2595
2596 //update auto test
2597 if(Config::getInstance().getBool("AutoTest")){
2598 AutoTest::getInstance().updateGame(this);
2599 return;
2600 }
2601
2602 if(showPerfStats) {
2603 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2604 perfList.push_back(perfBuf);
2605 }
2606
2607 if(world.getQueuedScenario() != "") {
2608 string name = world.getQueuedScenario();
2609 bool keepFactions = world.getQueuedScenarioKeepFactions();
2610 world.setQueuedScenario("",false);
2611
2612 //vector<string> results;
2613 const vector<string> &dirList = Config::getInstance().getPathListForType(ptScenarios);
2614 string scenarioFile = Scenario::getScenarioPath(dirList, name);
2615
2616
2617 try {
2618 gameStarted = false;
2619
2620 //printf("\nname [%s] scenarioFile [%s] results.size() = " MG_SIZE_T_SPECIFIER "\n",name.c_str(),scenarioFile.c_str(),results.size());
2621 //printf("[%s:%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
2622
2623 bool isTutorial = Scenario::isGameTutorial(scenarioFile);
2624 ScenarioInfo scenarioInfo;
2625 Scenario::loadScenarioInfo(scenarioFile, &scenarioInfo, isTutorial);
2626
2627 //printf("[%s:%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
2628 GameSettings gameSettings;
2629 Scenario::loadGameSettings(dirList,&scenarioInfo, &gameSettings, scenarioFile);
2630
2631 //Program *program = world->getGame()->getProgram();
2632 //program->setState(new Game(program, &gameSettings, false));
2633
2634 //world->end();
2635
2636 //world->getMapPtr()->end();
2637 //world.end();
2638
2639 if(keepFactions == false) {
2640 world.end();
2641
2642 world.cleanup();
2643 world.clearTileset();
2644
2645 SoundRenderer::getInstance().stopAllSounds();
2646
2647 masterController.clearSlaves(true);
2648 deleteValues(aiInterfaces.begin(), aiInterfaces.end());
2649 aiInterfaces.clear();
2650 gui.end(); //selection must be cleared before deleting units
2651 world.end(); //must die before selection because of referencers
2652
2653 BaseColorPickEntity::resetUniqueColors();
2654 // MUST DO THIS LAST!!!! Because objects above have pointers to things like
2655 // unit particles and fade them out etc and this end method deletes the original
2656 // object pointers.
2657 Renderer &renderer= Renderer::getInstance();
2658 renderer.endGame(true);
2659
2660 GameConstants::updateFps = original_updateFps;
2661 GameConstants::cameraFps = original_cameraFps;
2662
2663 this->setGameSettings(&gameSettings);
2664 this->resetMembers();
2665 this->load();
2666 this->init();
2667 }
2668 else {
2669 SoundRenderer &soundRenderer= SoundRenderer::getInstance();
2670 //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
2671 if(currentAmbientSound) {
2672 soundRenderer.stopAmbient(currentAmbientSound);
2673 }
2674 //soundRenderer.stopAllSounds();
2675 soundRenderer.stopAllSounds(fadeMusicMilliseconds);
2676
2677 world.endScenario();
2678 BaseColorPickEntity::resetUniqueColors();
2679
2680 Renderer &renderer= Renderer::getInstance();
2681 renderer.endScenario();
2682 world.clearTileset();
2683 this->setGameSettings(&gameSettings);
2684 this->load(lgt_FactionPreview | lgt_TileSet | lgt_Map | lgt_Scenario);
2685 try {
2686 world.init(this, gameSettings.getDefaultUnits(),false);
2687 }
2688 catch(const exception &ex) {
2689 char szBuf[8096]="";
2690 snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
2691
2692 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
2693 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
2694
2695 if(errorMessageBox.getEnabled() == false) {
2696 ErrorDisplayMessage(ex.what(),true);
2697 }
2698 }
2699
2700 world.initUnitsForScenario();
2701 Map *map= world.getMap();
2702 gameCamera.init(map->getW(), map->getH());
2703
2704 // camera default height calculation
2705 if(map->getCameraHeight()>0 && gameCamera.getCalculatedDefault()<map->getCameraHeight()){
2706 gameCamera.setCalculatedDefault(map->getCameraHeight());
2707 }
2708 else if(gameCamera.getCalculatedDefault()<map->getMaxMapHeight()+13.0f){
2709 gameCamera.setCalculatedDefault(map->getMaxMapHeight()+13.0f);
2710 }
2711
2712 scriptManager.init(&world, &gameCamera,loadGameNode);
2713 renderer.initGame(this,this->getGameCameraPtr());
2714
2715 //sounds
2716 //soundRenderer.stopAllSounds(fadeMusicMilliseconds);
2717 //soundRenderer.stopAllSounds();
2718 //soundRenderer= SoundRenderer::getInstance();
2719
2720 Tileset *tileset= world.getTileset();
2721 AmbientSounds *ambientSounds= tileset->getAmbientSounds();
2722
2723 //rain
2724 if(tileset->getWeather() == wRainy && ambientSounds->isEnabledRain()) {
2725 //logger.add("Starting ambient stream", true);
2726 currentAmbientSound = ambientSounds->getRain();
2727 //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
2728 soundRenderer.playAmbient(currentAmbientSound);
2729 }
2730
2731 //snow
2732 if(tileset->getWeather() == wSnowy && ambientSounds->isEnabledSnow()) {
2733 //logger.add("Starting ambient stream", true);
2734 currentAmbientSound = ambientSounds->getSnow();
2735 //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
2736 soundRenderer.playAmbient(currentAmbientSound);
2737 }
2738
2739 if(this->masterserverMode == false) {
2740 StrSound *gameMusic= world.getThisFaction()->getType()->getMusic();
2741 soundRenderer.playMusic(gameMusic);
2742 }
2743
2744 gameStarted = true;
2745 }
2746 //this->init();
2747
2748 //printf("[%s:%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
2749 //Checksum checksum;
2750 //world->loadScenario(scenarioFile, &checksum, true);
2751 }
2752 #if defined(WIN32)
2753 catch(const exception) {
2754 #else
2755 catch(const exception &ex) {
2756 #endif
2757 gameStarted = true;
2758 totalRenderFps++;
2759
2760 throw;
2761 }
2762 }
2763
2764 if(showPerfStats) {
2765 sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
2766 perfList.push_back(perfBuf);
2767 }
2768
2769 if(showPerfStats && chronoPerf.getMillis() >= 50) {
2770 for(unsigned int x = 0; x < (unsigned int)perfList.size(); ++x) {
2771 printf("%s",perfList[x].c_str());
2772 }
2773 }
2774 }
2775 catch(const exception &ex) {
2776 quitPendingIndicator = true;
2777
2778 char szBuf[8096]="";
2779 snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
2780
2781 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
2782 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
2783
2784 //printf("#100 quitPendingIndicator = %d, errorMessageBox.getEnabled() = %d\n",quitPendingIndicator,errorMessageBox.getEnabled());
2785
2786 NetworkManager &networkManager= NetworkManager::getInstance();
2787 if(networkManager.getGameNetworkInterface() != NULL) {
2788 GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
2789 networkInterface->sendTextMessage(szBuf,-1,true,"");
2790 sleep(10);
2791 networkManager.getGameNetworkInterface()->quitGame(true);
2792 }
2793 if(errorMessageBox.getEnabled() == false) {
2794 ErrorDisplayMessage(ex.what(),true);
2795 }
2796 }
2797 }
2798
2799 void Game::addPerformanceCount(string key,int64 value) {
2800 gamePerformanceCounts[key] = value + gamePerformanceCounts[key] / 2;
2801 }
2802
2803 string Game::getGamePerformanceCounts(bool displayWarnings) const {
2804 if(gamePerformanceCounts.empty() == true) {
2805 return "";
2806 }
2807
2808 bool displayWarningHeader = true;
2809 bool WARN_TO_CONSOLE = Config::getInstance().getBool("PerformanceWarningEnabled","false");
2810 int WARNING_MILLIS = Config::getInstance().getInt("PerformanceWarningMillis","7");
2811 int WARNING_RENDER_MILLIS = Config::getInstance().getInt("PerformanceWarningRenderMillis","40");
2812
2813 string result = "";
2814 for(std::map<string,int64>::const_iterator iterMap = gamePerformanceCounts.begin();
2815 iterMap != gamePerformanceCounts.end(); ++iterMap) {
2816 if(iterMap->first == ProgramState::MAIN_PROGRAM_RENDER_KEY) {
2817 if(iterMap->second < WARNING_RENDER_MILLIS) {
2818 continue;
2819 }
2820 //else {
2821 // printf("iterMap->second: " MG_I64_SPECIFIER " WARNING_RENDER_MILLIS = %d\n",iterMap->second,WARNING_RENDER_MILLIS);
2822 //}
2823 }
2824 else if(iterMap->second < WARNING_MILLIS) {
2825 continue;
2826 }
2827
2828 if(result != "") {
2829 result += "\n";
2830 }
2831 string perfStat = iterMap->first + " = avg millis: " + intToStr(iterMap->second);
2832
2833 if(displayWarnings == true && WARN_TO_CONSOLE == true) {
2834 if(displayWarningHeader == true) {
2835 displayWarningHeader = false;
2836 printf("=====================================\nPERFORMANCE WARNINGS for World Frame: %d\n",world.getFrameCount());
2837 }
2838
2839 printf("*PERFORMANCE WARNING* %s\n",perfStat.c_str());
2840 }
2841
2842 result += perfStat;
2843 }
2844
2845 return result;
2846 }
2847
2848 bool Game::switchSetupForSlots(ServerInterface *& serverInterface,
2849 int startIndex, int endIndex, bool onlyNetworkUnassigned) {
2850 bool switchRequested = false;
2851 if(serverInterface == NULL) {
2852 return switchRequested;
2853 }
2854
2855 MutexSafeWrapper safeMutex(serverInterface->getSwitchSetupRequestsMutex(),CODE_AT_LINE);
2856 SwitchSetupRequest ** switchSetupRequests = serverInterface->getSwitchSetupRequests();
2857 if(switchSetupRequests == NULL) {
2858 return switchRequested;
2859 }
2860
2861 Map *map= world.getMap();
2862 for(int i= startIndex; i < endIndex; ++i) {
2863 if(switchSetupRequests[i] != NULL) {
2864 //printf("Faction Index: %d Switch slot = %d to = %d current control = %d\n",i,switchSetupRequests[i]->getCurrentSlotIndex(),switchSetupRequests[i]->getToSlotIndex(),gameSettings.getFactionControl(i));
2865
2866 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] switchSetupRequests[i]->getSwitchFlags() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,switchSetupRequests[i]->getSwitchFlags());
2867
2868 if(onlyNetworkUnassigned == true && gameSettings.getFactionControl(i) != ctNetworkUnassigned) {
2869 if(i < map->getMaxPlayers() || (i >= map->getMaxPlayers() && gameSettings.getFactionControl(i) != ctNetwork)) {
2870 continue;
2871 }
2872 }
2873
2874 if(gameSettings.getFactionControl(i) == ctNetwork ||
2875 gameSettings.getFactionControl(i) == ctNetworkUnassigned ||
2876 //(gameSettings.getFactionControl(i) != ctClosed && gameSettings.getFactionControl(i) != ctHuman)) {
2877 (gameSettings.getFactionControl(i) != ctHuman)) {
2878 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] switchSetupRequests[i]->getToFactionIndex() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,switchSetupRequests[i]->getToSlotIndex());
2879
2880 if(switchSetupRequests[i]->getToSlotIndex() != -1) {
2881 int newSlotIdx = switchSetupRequests[i]->getToSlotIndex();
2882
2883 //printf("switchSlot request from %d to %d\n",switchSetupRequests[i]->getCurrentSlotIndex(),switchSetupRequests[i]->getToSlotIndex());
2884
2885 int switchSlotIdx = switchSetupRequests[i]->getCurrentSlotIndex();
2886 if(serverInterface->switchSlot(switchSlotIdx,newSlotIdx)) {
2887 //printf("switchSlot returned true\n");
2888 switchRequested = true;
2889
2890 int oldFactionIndex = gameSettings.getFactionIndexForStartLocation(switchSlotIdx);
2891 int newFactionIndex = gameSettings.getFactionIndexForStartLocation(newSlotIdx);
2892
2893 //printf("Switching faction for index %d [%d] to %d\n",newSlotIdx,switchSlotIdx,gameSettings.getFactionControl(newFactionIndex));
2894
2895 gameSettings.setNetworkPlayerName(oldFactionIndex, "");
2896 serverInterface->gameSettings.setNetworkPlayerName(oldFactionIndex, "");
2897 gameSettings.setNetworkPlayerUUID(oldFactionIndex, "");
2898 serverInterface->gameSettings.setNetworkPlayerUUID(oldFactionIndex, "");
2899
2900 gameSettings.setNetworkPlayerPlatform(oldFactionIndex, "");
2901 serverInterface->gameSettings.setNetworkPlayerPlatform(oldFactionIndex, "");
2902
2903 gameSettings.setFactionControl(newFactionIndex,ctNetwork);
2904 serverInterface->gameSettings.setFactionControl(newFactionIndex,ctNetwork);
2905
2906 //printf("#1a Faction Index: %d control: %d startlocation: %d\n",newFactionIndex,gameSettings.getFactionControl(newFactionIndex),gameSettings.getStartLocationIndex(newFactionIndex));
2907 //printf("#2a Faction Index: %d control: %d startlocation: %d\n",newFactionIndex,serverInterface->gameSettings.getFactionControl(newFactionIndex),serverInterface->gameSettings.getStartLocationIndex(newFactionIndex));
2908
2909 try {
2910 //if(switchSetupRequests[i]->getSelectedFactionName() != "") {
2911 // listBoxFactions[newFactionIdx].setSelectedItem(switchSetupRequests[i]->getSelectedFactionName());
2912 //}
2913 //if(switchSetupRequests[i]->getToTeam() != -1) {
2914 // listBoxTeams[newFactionIdx].setSelectedItemIndex(switchSetupRequests[i]->getToTeam());
2915 //}
2916 if(switchSetupRequests[i]->getNetworkPlayerName() != "") {
2917 //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] i = %d, labelPlayerNames[newFactionIdx].getText() [%s] switchSetupRequests[i]->getNetworkPlayerName() [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,labelPlayerNames[newFactionIdx].getText().c_str(),switchSetupRequests[i]->getNetworkPlayerName().c_str());
2918 gameSettings.setNetworkPlayerName(newFactionIndex,switchSetupRequests[i]->getNetworkPlayerName());
2919 serverInterface->gameSettings.setNetworkPlayerName(newFactionIndex,switchSetupRequests[i]->getNetworkPlayerName());
2920 }
2921
2922 // if(gameSettings.getFactionControl(switchFactionIdx) == ctNetworkUnassigned) {
2923 // serverInterface->removeSlot(switchFactionIdx);
2924 // //listBoxControls[switchFactionIdx].setSelectedItemIndex(ctClosed);
2925 // gameSettings.getFactionControl(switchFactionIdx)
2926 //
2927 // labelPlayers[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players);
2928 // labelPlayerNames[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players);
2929 // listBoxControls[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players);
2930 // listBoxFactions[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players);
2931 // listBoxTeams[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players);
2932 // labelNetStatus[switchSlotIdx].setVisible(switchSlotIdx+1 <= mapInfo.players);
2933 // }
2934 }
2935 catch(const runtime_error &e) {
2936 SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
2937 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] caught exception error = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
2938 }
2939 }
2940 //printf("AFTER switchSlot returned\n");
2941 }
2942 else {
2943 try {
2944 //if(switchSetupRequests[i]->getSelectedFactionName() != "") {
2945 // listBoxFactions[i].setSelectedItem(switchSetupRequests[i]->getSelectedFactionName());
2946 //}
2947 //if(switchSetupRequests[i]->getToTeam() != -1) {
2948 // listBoxTeams[i].setSelectedItemIndex(switchSetupRequests[i]->getToTeam());
2949 //}
2950
2951 if((switchSetupRequests[i]->getSwitchFlags() & ssrft_NetworkPlayerName) == ssrft_NetworkPlayerName) {
2952 //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, switchSetupRequests[i]->getSwitchFlags() = %d, switchSetupRequests[i]->getNetworkPlayerName() [%s], labelPlayerNames[i].getText() [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,switchSetupRequests[i]->getSwitchFlags(),switchSetupRequests[i]->getNetworkPlayerName().c_str(),labelPlayerNames[i].getText().c_str());
2953
2954 if(switchSetupRequests[i]->getNetworkPlayerName() != GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) {
2955 //labelPlayerNames[i].setText(switchSetupRequests[i]->getNetworkPlayerName());
2956 gameSettings.setNetworkPlayerName(i,switchSetupRequests[i]->getNetworkPlayerName());
2957 serverInterface->gameSettings.setNetworkPlayerName(i,switchSetupRequests[i]->getNetworkPlayerName());
2958 switchRequested = true;
2959 }
2960 else {
2961 //labelPlayerNames[i].setText("");
2962 gameSettings.setNetworkPlayerName(i,"");
2963 serverInterface->gameSettings.setNetworkPlayerName(i,"");
2964 switchRequested = true;
2965 }
2966 //SetActivePlayerNameEditor();
2967 //switchSetupRequests[i]->clearSwitchFlag(ssrft_NetworkPlayerName);
2968 }
2969 }
2970 catch(const runtime_error &e) {
2971 SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
2972 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] caught exception error = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
2973 }
2974 }
2975 }
2976
2977 delete switchSetupRequests[i];
2978 switchSetupRequests[i]=NULL;
2979 }
2980 }
2981
2982 return switchRequested;
2983 }
2984
2985 void Game::updateNetworkMarkedCells() {
2986 try {
2987 GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
2988
2989 if(gameNetworkInterface != NULL &&
2990 gameNetworkInterface->getMarkedCellList(false).empty() == false) {
2991
2992 std::vector<MarkedCell> chatList = gameNetworkInterface->getMarkedCellList(true);
2993 for(int idx = 0; idx < (int)chatList.size(); idx++) {
2994 MarkedCell mc = chatList[idx];
2995 if(mc.getFactionIndex() >= 0) {
2996 mc.setFaction((const Faction *)world.getFaction(mc.getFactionIndex()));
2997 }
2998
2999 Map *map= world.getMap();
3000 Vec2i surfaceCellPos = map->toSurfCoords(mc.getTargetPos());
3001 mapMarkedCellList[surfaceCellPos] = mc;
3002 }
3003 }
3004 }
3005 catch(const std::exception &ex) {
3006 char szBuf[8096]="";
3007 snprintf(szBuf,8096,"In [%s::%s %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
3008 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
3009 throw megaglest_runtime_error(szBuf);
3010 }
3011 }
3012
3013 void Game::updateNetworkUnMarkedCells() {
3014 try {
3015 GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
3016
3017 if(gameNetworkInterface != NULL &&
3018 gameNetworkInterface->getUnMarkedCellList(false).empty() == false) {
3019 //Lang &lang= Lang::getInstance();
3020
3021 std::vector<UnMarkedCell> chatList = gameNetworkInterface->getUnMarkedCellList(true);
3022 for(int idx = 0; idx < (int)chatList.size(); idx++) {
3023 UnMarkedCell mc = chatList[idx];
3024 mc.setFaction((const Faction *)world.getFaction(mc.getFactionIndex()));
3025
3026 Map *map= world.getMap();
3027 Vec2i surfaceCellPos = map->toSurfCoords(mc.getTargetPos());
3028 mapMarkedCellList.erase(surfaceCellPos);
3029 }
3030 }
3031 }
3032 catch(const std::exception &ex) {
3033 char szBuf[8096]="";
3034 snprintf(szBuf,8096,"In [%s::%s %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
3035 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
3036 throw megaglest_runtime_error(szBuf);
3037 }
3038 }
3039
3040
3041 void Game::updateNetworkHighligtedCells() {
3042 try {
3043 GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
3044
3045 //update the current entries
3046 for(int idx = (int)highlightedCells.size()-1; idx >= 0; idx--) {
3047 MarkedCell *mc = &highlightedCells[idx];
3048 mc->decrementAliveCount();
3049 if(mc->getAliveCount() < 0) {
3050 highlightedCells.erase(highlightedCells.begin()+idx);
3051 }
3052 }
3053
3054 if(gameNetworkInterface != NULL &&
3055 gameNetworkInterface->getHighlightedCellList(false).empty() == false) {
3056 //Lang &lang= Lang::getInstance();
3057 std::vector<MarkedCell> highlighList = gameNetworkInterface->getHighlightedCellList(true);
3058 for(int idx = 0; idx < (int)highlighList.size(); idx++) {
3059 MarkedCell mc = highlighList[idx]; // I want a copy here
3060 if(mc.getFactionIndex() >= 0) {
3061 mc.setFaction((const Faction *)world.getFaction(mc.getFactionIndex())); // set faction pointer
3062 }
3063 addOrReplaceInHighlightedCells(mc);
3064 }
3065 }
3066 }
3067 catch(const std::exception &ex) {
3068 char szBuf[8096]="";
3069 snprintf(szBuf,8096,"In [%s::%s %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
3070 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
3071 throw megaglest_runtime_error(szBuf);
3072 }
3073 }
3074
3075 void Game::addOrReplaceInHighlightedCells(MarkedCell mc){
3076 if(mc.getFactionIndex() >= 0) {
3077 for(int i = (int)highlightedCells.size()-1; i >= 0; i--) {
3078 MarkedCell *currentMc = &highlightedCells[i];
3079 if(currentMc->getFactionIndex() == mc.getFactionIndex()) {
3080 highlightedCells.erase(highlightedCells.begin()+i);
3081 }
3082 }
3083 }
3084 if(mc.getAliveCount() <= 0) {
3085 mc.setAliveCount(200);
3086 }
3087 highlightedCells.push_back(mc);
3088
3089 if (this->masterserverMode == false) {
3090 CoreData &coreData= CoreData::getInstance();
3091 SoundRenderer &soundRenderer= SoundRenderer::getInstance();
3092
3093 const Faction *faction = mc.getFaction();
3094 if(getWorld()->getThisFaction() == NULL) {
3095 throw megaglest_runtime_error("getWorld()->getThisFaction() == NULL");
3096 }
3097 //printf("faction [%p][%s]\n",faction,(faction != NULL ? faction->getType()->getName().c_str() : ""));
3098 if((faction == NULL) ||
3099 (faction->getTeam() == getWorld()->getThisFaction()->getTeam())) {
3100 soundRenderer.playFx(coreData.getMarkerSound(),true);
3101 }
3102 }
3103 }
3104
3105 void Game::ReplaceDisconnectedNetworkPlayersWithAI(bool isNetworkGame, NetworkRole role) {
3106 if(role == nrServer && isNetworkGame == true &&
3107 difftime((long int)time(NULL),lastNetworkPlayerConnectionCheck) >= NETWORK_PLAYER_CONNECTION_CHECK_SECONDS) {
3108 lastNetworkPlayerConnectionCheck = time(NULL);
3109 Logger &logger= Logger::getInstance();
3110 ServerInterface *server = NetworkManager::getInstance().getServerInterface();
3111
3112 bool newAIPlayerCreated = false;
3113 for(int i = 0; i < world.getFactionCount(); ++i) {
3114 Faction *faction = world.getFaction(i);
3115 if( faction->getFactionDisconnectHandled() == false &&
3116 (faction->getControlType() == ctNetwork ||
3117 faction->getControlType() == ctNetworkCpuEasy ||
3118 faction->getControlType() == ctNetworkCpu ||
3119 faction->getControlType() == ctNetworkCpuUltra ||
3120 faction->getControlType() == ctNetworkCpuMega)) {
3121
3122 if(aiInterfaces[i] == NULL &&
3123 server->isClientConnected(faction->getStartLocationIndex()) == false) {
3124
3125 if(faction->getPersonalityType() != fpt_Observer) {
3126 DumpCRCWorldLogIfRequired("_faction_" + intToStr(i));
3127 }
3128
3129 faction->setFactionDisconnectHandled(true);
3130
3131 Lang &lang= Lang::getInstance();
3132
3133 bool isPlayerObserver = false;
3134 char szBuf[8096]="";
3135 if(faction->getPersonalityType() != fpt_Observer) {
3136 aiInterfaces[i] = new AiInterface(*this, i, faction->getTeam(), faction->getStartLocationIndex());
3137
3138 snprintf(szBuf,8096,Lang::getInstance().getString("LogScreenGameLoadingCreatingAIFaction","",true).c_str(),i);
3139 logger.add(szBuf, true);
3140
3141 commander.tryNetworkPlayerDisconnected(i);
3142
3143 newAIPlayerCreated = true;
3144 }
3145 else {
3146 isPlayerObserver = true;
3147
3148 }
3149
3150 const vector<string> languageList = this->gameSettings.getUniqueNetworkPlayerLanguages();
3151 for(unsigned int j = 0; j < (unsigned int)languageList.size(); ++j) {
3152 if(isPlayerObserver == false) {
3153 string msg = "Player #%d [%s] has disconnected, switching player to AI mode!";
3154 if(lang.hasString("GameSwitchPlayerToAI",languageList[j],true)) {
3155 msg = lang.getString("GameSwitchPlayerToAI",languageList[j],true);
3156 }
3157 snprintf(szBuf,8096,msg.c_str(),i+1,this->gameSettings.getNetworkPlayerName(i).c_str());
3158 }
3159 else {
3160 string msg = "Player #%d [%s] has disconnected, but player was only an observer!";
3161 if(lang.hasString("GameSwitchPlayerObserverToAI",languageList[j],true)) {
3162 msg = lang.getString("GameSwitchPlayerObserverToAI",languageList[j],true);
3163 }
3164 snprintf(szBuf,8096,msg.c_str(),i+1,this->gameSettings.getNetworkPlayerName(i).c_str());
3165 }
3166 bool localEcho = (languageList[j] == lang.getLanguage());
3167 server->sendTextMessage(szBuf,-1,localEcho,languageList[j]);
3168 }
3169 }
3170 }
3171 }
3172
3173 if(newAIPlayerCreated == true && Config::getInstance().getBool("EnableNewThreadManager","false") == true) {
3174 bool enableServerControlledAI = this->gameSettings.getEnableServerControlledAI();
3175
3176 masterController.clearSlaves(true);
3177
3178 std::vector<SlaveThreadControllerInterface *> slaveThreadList;
3179 for(int i=0; i < world.getFactionCount(); ++i) {
3180 Faction *faction= world.getFaction(i);
3181 if(faction->getCpuControl(enableServerControlledAI,isNetworkGame,role) == true) {
3182 slaveThreadList.push_back(aiInterfaces[i]->getWorkerThread());
3183 }
3184 }
3185 masterController.setSlaves(slaveThreadList);
3186 }
3187 }
3188 }
3189
3190 void Game::updateCamera(){
3191 if(currentUIState != NULL) {
3192 currentUIState->updateCamera();
3193 return;
3194 }
3195 gameCamera.update();
3196 }
3197
3198
3199 // ==================== render ====================
3200
3201 //render
3202 void Game::render() {
3203 // Ensure the camera starts in the right position
3204 if(isFirstRender == true) {
3205 isFirstRender = false;
3206
3207 if(this->loadGameNode == NULL) {
3208 gameCamera.setState(GameCamera::sGame);
3209 this->restoreToStartXY();
3210 }
3211 }
3212
3213 canRender();
3214 incrementFps();
3215
3216 renderFps++;
3217 totalRenderFps++;
3218
3219 updateWorldStats();
3220
3221 //NetworkManager &networkManager= NetworkManager::getInstance();
3222 if(this->masterserverMode == false) {
3223 renderWorker();
3224 }
3225 else {
3226 // Titi, uncomment this to watch the game on the masterserver
3227 //renderWorker();
3228
3229 // In masterserver mode quit game if no network players left
3230 ServerInterface *server = NetworkManager::getInstance().getServerInterface();
3231 int connectedClients=0;
3232 for(int i = 0; i < world.getFactionCount(); ++i) {
3233 Faction *faction = world.getFaction(i);
3234 if(server->isClientConnected(faction->getStartLocationIndex()) == true) {
3235 connectedClients++;
3236 }
3237 }
3238
3239 if(connectedClients == 0) {
3240 quitTriggeredIndicator = true;
3241 }
3242 else {
3243 string str="";
3244 std::map<int,string> factionDebugInfo;
3245
3246 if( difftime((long int)time(NULL),lastMasterServerGameStatsDump) >= GAME_STATS_DUMP_INTERVAL) {
3247 lastMasterServerGameStatsDump = time(NULL);
3248 str = getDebugStats(factionDebugInfo);
3249
3250 printf("== Current in-game stats (interval %d) ==\n%s\n",GAME_STATS_DUMP_INTERVAL,str.c_str());
3251 }
3252 }
3253 }
3254 }
3255
3256 void Game::renderWorker() {
3257 if(currentUIState != NULL) {
3258 // Renderer &renderer= Renderer::getInstance();
3259 // renderer.clearBuffers();
3260 //
3261 // //3d
3262 // renderer.reset3dMenu();
3263 //
3264 // renderer.clearZBuffer();
3265 // //renderer.loadCameraMatrix(menuBackground.getCamera());
3266 // //renderer.renderMenuBackground(&menuBackground);
3267 // renderer.renderParticleManager(rsMenu);
3268 //
3269 // //2d
3270 // renderer.reset2d();
3271 //
3272 // currentUIState->render();
3273 //
3274 // if(renderer.isMasterserverMode() == false) {
3275 // renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim);
3276 // renderer.renderFPSWhenEnabled(lastFps);
3277 // renderer.swapBuffers();
3278 // }
3279
3280 currentUIState->render();
3281 return;
3282 }
3283 else {
3284 Renderer &renderer= Renderer::getInstance();
3285 if(renderer.getCustom3dMenu() != NULL) {
3286 renderer.setCustom3dMenu(NULL);
3287 }
3288 }
3289
3290 Chrono chrono;
3291 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
3292
3293 render3d();
3294
3295 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %d [render3d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
3296 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
3297
3298 render2d();
3299
3300 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %d [render2d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
3301 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
3302
3303 Renderer::getInstance().swapBuffers();
3304 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %d [swap buffers]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
3305 }
3306
3307 // ==================== tick ====================
3308
3309 void Game::removeUnitFromSelection(const Unit *unit) {
3310 try {
3311 Selection *selection= gui.getSelectionPtr();
3312 for(int i=0; i < selection->getCount(); ++i) {
3313 const Unit *currentUnit = selection->getUnit(i);
3314 if(currentUnit == unit) {
3315 selection->unSelect(i);
3316 break;
3317 }
3318 }
3319 }
3320 catch(const exception &ex) {
3321 char szBuf[8096]="";
3322 snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
3323
3324 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
3325 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
3326
3327 if(errorMessageBox.getEnabled() == false) {
3328 ErrorDisplayMessage(ex.what(),true);
3329 }
3330
3331 //abort();
3332 }
3333 }
3334
3335 bool Game::addUnitToSelection(Unit *unit) {
3336 bool result = false;
3337 try {
3338 Selection *selection= gui.getSelectionPtr();
3339 if(selection != NULL) {
3340 result = selection->select(unit,true);
3341 }
3342 }
3343 catch(const exception &ex) {
3344 char szBuf[8096]="";
3345 snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
3346
3347 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
3348 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
3349
3350 if(errorMessageBox.getEnabled() == false) {
3351 ErrorDisplayMessage(ex.what(),true);
3352 }
3353
3354 //abort();
3355 }
3356
3357 return result;
3358 }
3359
3360 void Game::addUnitToGroupSelection(Unit *unit,int groupIndex) {
3361 try {
3362 Selection *selection= gui.getSelectionPtr();
3363 if(selection != NULL) {
3364 selection->addUnitToGroup(groupIndex,unit);
3365 }
3366 }
3367 catch(const exception &ex) {
3368 char szBuf[8096]="";
3369 snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
3370
3371 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
3372 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
3373
3374 if(errorMessageBox.getEnabled() == false) {
3375 ErrorDisplayMessage(ex.what(),true);
3376 }
3377
3378 //abort();
3379 }
3380 }
3381
3382 void Game::removeUnitFromGroupSelection(int unitId,int groupIndex) {
3383 try {
3384 Selection *selection= gui.getSelectionPtr();
3385 if(selection != NULL) {
3386 selection->removeUnitFromGroup(groupIndex,unitId);
3387 }
3388 }
3389 catch(const exception &ex) {
3390 char szBuf[8096]="";
3391 snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
3392
3393 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
3394 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
3395
3396 if(errorMessageBox.getEnabled() == false) {
3397 ErrorDisplayMessage(ex.what(),true);
3398 }
3399
3400 //abort();
3401 }
3402 }
3403
3404 void Game::recallGroupSelection(int groupIndex) {
3405 try {
3406 Selection *selection= gui.getSelectionPtr();
3407 if(selection != NULL) {
3408 selection->recallGroup(groupIndex);
3409 }
3410 }
3411 catch(const exception &ex) {
3412 char szBuf[8096]="";
3413 snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
3414
3415 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
3416 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
3417
3418 if(errorMessageBox.getEnabled() == false) {
3419 ErrorDisplayMessage(ex.what(),true);
3420 }
3421
3422 //abort();
3423 }
3424 }
3425
3426 void Game::tick() {
3427 ProgramState::tick();
3428
3429 tickCount++;
3430
3431 if(avgUpdateFps == -1) {
3432 avgUpdateFps = updateFps;
3433 }
3434 else {
3435 avgUpdateFps = (avgUpdateFps + updateFps) / 2;
3436 }
3437 currentAvgRenderFpsTotal += renderFps;
3438
3439 if(avgRenderFps == -1) {
3440 avgRenderFps = renderFps;
3441 }
3442 // Update the average every x game ticks
3443 const int CHECK_AVG_FPS_EVERY_X_TICKS = 15;
3444 if(tickCount % CHECK_AVG_FPS_EVERY_X_TICKS == 0) {
3445 avgRenderFps = currentAvgRenderFpsTotal / CHECK_AVG_FPS_EVERY_X_TICKS;
3446 currentAvgRenderFpsTotal = 0;
3447 }
3448
3449 if(captureAvgTestStatus == true) {
3450 if(updateFpsAvgTest == -1) {
3451 updateFpsAvgTest = updateFps;
3452 }
3453 else {
3454 updateFpsAvgTest = (updateFpsAvgTest + updateFps) / 2;
3455 }
3456 if(renderFpsAvgTest == -1) {
3457 renderFpsAvgTest = renderFps;
3458 }
3459 else {
3460 renderFpsAvgTest = (renderFpsAvgTest + renderFps) / 2;
3461 }
3462 }
3463
3464 lastUpdateFps= updateFps;
3465 lastRenderFps= renderFps;
3466 updateFps= 0;
3467 renderFps= 0;
3468
3469 //Win/lose check
3470 checkWinner();
3471 gui.tick();
3472 }
3473
3474
3475 // ==================== events ====================
3476
3477 int Game::getFirstUnusedTeamNumber() {
3478 std::map<int,bool> uniqueTeamNumbersUsed;
3479 for(unsigned int i = 0; i < (unsigned int)world.getFactionCount(); ++i) {
3480 Faction *faction = world.getFaction(i);
3481 uniqueTeamNumbersUsed[faction->getTeam()]=true;
3482 }
3483
3484 int result = -1;
3485 for(int i = 0; i < GameConstants::maxPlayers; ++i) {
3486 if(uniqueTeamNumbersUsed.find(i) == uniqueTeamNumbersUsed.end()) {
3487 result = i;
3488 break;
3489 }
3490 }
3491
3492 return result;
3493 }
3494
3495 void Game::setupRenderForVideo() {
3496 Renderer &renderer= Renderer::getInstance();
3497 //renderer.clearBuffers();
3498 //3d
3499 //renderer.reset3dMenu();
3500 //renderer.clearZBuffer();
3501 //2d
3502 //renderer.reset2d();
3503 renderer.setupRenderForVideo();
3504 }
3505
3506 void Game::tryPauseToggle(bool pauseValue) {
3507 bool allowAdminMenuItems = false;
3508 NetworkManager &networkManager= NetworkManager::getInstance();
3509 NetworkRole role = networkManager.getNetworkRole();
3510 if(role == nrServer) {
3511 allowAdminMenuItems = true;
3512 }
3513 else if(role == nrClient) {
3514 ClientInterface *clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
3515
3516 if(clientInterface != NULL &&
3517 gameSettings.getMasterserver_admin() == clientInterface->getSessionKey()) {
3518 allowAdminMenuItems = true;
3519 }
3520 }
3521
3522 bool isNetworkGame = this->gameSettings.isNetworkGame();
3523 //printf("Try Pause allowAdminMenuItems = %d, pauseValue = %d\n",allowAdminMenuItems,pauseValue);
3524
3525 if(allowAdminMenuItems) {
3526 if(pauseValue == true) {
3527 commander.tryPauseGame(false,false);
3528 }
3529 else {
3530 if(isNetworkGame == false) {
3531 setPaused(pauseValue, true,false,false);
3532 }
3533 else {
3534 commander.tryResumeGame(false,false);
3535 }
3536 }
3537 }
3538 }
3539
3540 void Game::startMarkCell() {
3541 int totalMarkedCellsForPlayer = 0;
3542 if(world.getThisFaction() != NULL) {
3543 for(std::map<Vec2i, MarkedCell>::iterator iterMap = mapMarkedCellList.begin();
3544 iterMap != mapMarkedCellList.end(); ++iterMap) {
3545 MarkedCell &bm = iterMap->second;
3546 if(bm.getPlayerIndex() == world.getThisFaction()->getStartLocationIndex()) {
3547 totalMarkedCellsForPlayer++;
3548 }
3549 }
3550 }
3551
3552 const int MAX_MARKER_COUNT = 5;
3553 if(totalMarkedCellsForPlayer < MAX_MARKER_COUNT) {
3554 isMarkCellEnabled = true;
3555 }
3556 else {
3557 Lang &lang= Lang::getInstance();
3558 console.addLine(lang.getString("MaxMarkerCount") + " " + intToStr(MAX_MARKER_COUNT));
3559 }
3560 }
3561
3562 void Game::processInputText(string text, bool cancelled) {
3563 isMarkCellTextEnabled = false;
3564
3565 if(cancelled == false) {
3566 //printf("Note [%s]\n",text.c_str());
3567
3568 cellMarkedData.setNote(text);
3569 addCellMarker(cellMarkedPos, cellMarkedData);
3570
3571 // if(text.find("\\n") != text.npos) {
3572 // replaceAll(text, "\\n", "\n");
3573 // }
3574 // if(text.find("\\t") != text.npos) {
3575 // replaceAll(text, "\\t", "\t");
3576 // }
3577 //
3578 // cellMarkedData.setNote(text);
3579 // mapMarkedCellList[cellMarkedPos] = cellMarkedData;
3580 //
3581 // GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
3582 //
3583 // int factionIndex = -1;
3584 // int playerIndex = -1;
3585 // if(cellMarkedData.getFaction() != NULL) {
3586 // factionIndex = cellMarkedData.getFaction()->getIndex();
3587 // playerIndex = cellMarkedData.getFaction()->getStartLocationIndex();
3588 // }
3589 // gameNetworkInterface->sendMarkCellMessage(
3590 // cellMarkedData.getTargetPos(),
3591 // factionIndex,
3592 // cellMarkedData.getNote(),
3593 // playerIndex);
3594 //
3595 // Renderer &renderer= Renderer::getInstance();
3596 // renderer.forceQuadCacheUpdate();
3597 }
3598 }
3599
3600 void Game::addCellMarker(Vec2i cellPos, MarkedCell cellData) {
3601 //printf("Note [%s]\n",text.c_str());
3602
3603 string text = cellData.getNote();
3604 if(text.find("\\n") != text.npos) {
3605 replaceAll(text, "\\n", "\n");
3606 }
3607 if(text.find("\\t") != text.npos) {
3608 replaceAll(text, "\\t", "\t");
3609 }
3610
3611 cellData.setNote(text);
3612 mapMarkedCellList[cellPos] = cellData;
3613
3614 GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
3615
3616 int factionIndex = -1;
3617 int playerIndex = -1;
3618 if(cellData.getFaction() != NULL) {
3619 factionIndex = cellData.getFaction()->getIndex();
3620 playerIndex = cellData.getFaction()->getStartLocationIndex();
3621 }
3622
3623 //printf("Adding Cell marker pos [%s] factionIndex [%d] note [%s] playerIndex = %d\n",cellData.getTargetPos().getString().c_str(),factionIndex,cellData.getNote().c_str(),playerIndex);
3624
3625 gameNetworkInterface->sendMarkCellMessage(
3626 cellData.getTargetPos(),
3627 factionIndex,
3628 cellData.getNote(),
3629 playerIndex);
3630
3631 Renderer &renderer= Renderer::getInstance();
3632 renderer.forceQuadCacheUpdate();
3633 }
3634
3635 void Game::removeCellMarker(Vec2i surfaceCellPos, const Faction *faction) {
3636 //Vec2i surfaceCellPos = map->toSurfCoords(Vec2i(xCell,yCell));
3637 Map *map= world.getMap();
3638 SurfaceCell *sc = map->getSurfaceCell(surfaceCellPos);
3639 Vec3f vertex = sc->getVertex();
3640 Vec2i targetPos(vertex.x,vertex.z);
3641
3642 //printf("Remove Cell marker lookup pos [%s] factionIndex [%d]\n",surfaceCellPos.getString().c_str(),(faction != NULL ? faction->getIndex() : -1));
3643
3644 if(mapMarkedCellList.find(surfaceCellPos) != mapMarkedCellList.end()) {
3645 MarkedCell mc = mapMarkedCellList[surfaceCellPos];
3646 if(mc.getFaction() == faction) {
3647 mapMarkedCellList.erase(surfaceCellPos);
3648 GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
3649
3650 int factionIndex = (faction != NULL ? faction->getIndex() : -1);
3651
3652 //printf("Remvoing Cell marker pos [%s] factionIndex [%d] note [%s]\n",mc.getTargetPos().getString().c_str(),factionIndex,mc.getNote().c_str());
3653
3654 gameNetworkInterface->sendUnMarkCellMessage(mc.getTargetPos(),factionIndex);
3655 }
3656 }
3657 //printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size());
3658
3659 //isUnMarkCellEnabled = false;
3660
3661 Renderer &renderer= Renderer::getInstance();
3662 //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos);
3663 renderer.forceQuadCacheUpdate();
3664 }
3665 void Game::showMarker(Vec2i cellPos, MarkedCell cellData) {
3666 //setMarker = true;
3667 //if(setMarker) {
3668 //Vec2i targetPos = cellData.targetPos;
3669 //Vec2i screenPos(x,y-60);
3670 //Renderer &renderer= Renderer::getInstance();
3671 //renderer.computePosition(screenPos, targetPos);
3672 //Vec2i surfaceCellPos = map->toSurfCoords(targetPos);
3673
3674 //MarkedCell mc(targetPos,world.getThisFaction(),"none",world.getThisFaction()->getStartLocationIndex());
3675 addOrReplaceInHighlightedCells(cellData);
3676
3677 GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
3678 gameNetworkInterface->sendHighlightCellMessage(cellData.getTargetPos(),cellData.getFactionIndex());
3679 //}
3680 }
3681
3682 void Game::mouseDownLeft(int x, int y) {
3683 if(this->masterserverMode == true) {
3684 return;
3685 }
3686 cameraDragAllowed=false;
3687 if(currentUIState != NULL) {
3688 currentUIState->mouseDownLeft(x, y);
3689 return;
3690 }
3691
3692 try {
3693 if(gameStarted == false || totalRenderFps <= 0) {
3694 Logger::getInstance().handleMouseClick(x, y);
3695 return;
3696 }
3697
3698 Map *map= world.getMap();
3699 const Metrics &metrics= Metrics::getInstance();
3700 NetworkManager &networkManager= NetworkManager::getInstance();
3701 bool messageBoxClick= false;
3702 bool originalIsMarkCellEnabled = isMarkCellEnabled;
3703 bool originalIsUnMarkCellEnabled = isUnMarkCellEnabled;
3704
3705 if(popupMenu.mouseClick(x, y)) {
3706 std::pair<int,string> result = popupMenu.mouseClickedMenuItem(x, y);
3707 //printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first);
3708
3709 //printf("popupMenu.mouseClick == true result.first = %d disconnectPlayerPopupMenuIndex = %d\n",result.first,disconnectPlayerPopupMenuIndex);
3710
3711 popupMenu.setEnabled(false);
3712 popupMenu.setVisible(false);
3713
3714 // Exit game
3715 if(result.first == exitGamePopupMenuIndex) {
3716 showMessageBox(Lang::getInstance().getString("ExitBattleQuestion"), "", true);
3717 }
3718 else if(result.first == joinTeamPopupMenuIndex) {
3719
3720 Lang &lang= Lang::getInstance();
3721 switchTeamIndexMap.clear();
3722 std::map<int,bool> uniqueTeamNumbersUsed;
3723 std::vector<string> menuItems;
3724 for(unsigned int i = 0; i < (unsigned int)world.getFactionCount(); ++i) {
3725 Faction *faction = world.getFaction(i);
3726
3727 if(faction->getPersonalityType() != fpt_Observer &&
3728 uniqueTeamNumbersUsed.find(faction->getTeam()) == uniqueTeamNumbersUsed.end()) {
3729 uniqueTeamNumbersUsed[faction->getTeam()] = true;
3730 }
3731
3732 if(faction->getPersonalityType() != fpt_Observer &&
3733 world.getThisFaction()->getIndex() != faction->getIndex() &&
3734 world.getThisFaction()->getTeam() != faction->getTeam()) {
3735 char szBuf[8096]="";
3736 if(lang.hasString("JoinPlayerTeam") == true) {
3737 snprintf(szBuf,8096,(" " + lang.getString("JoinPlayerTeam") + " ").c_str(),faction->getIndex(),this->gameSettings.getNetworkPlayerName(i).c_str(),faction->getTeam());
3738 }
3739 else {
3740 snprintf(szBuf,8096," Join player #%d - %s on Team: %d ",faction->getIndex(),this->gameSettings.getNetworkPlayerName(i).c_str(),faction->getTeam());
3741 }
3742
3743 menuItems.push_back(szBuf);
3744
3745 switchTeamIndexMap[(int)menuItems.size()-1] = faction->getTeam();
3746 }
3747 }
3748
3749 if((int)uniqueTeamNumbersUsed.size() < 8) {
3750 menuItems.push_back(" " + lang.getString("CreateNewTeam") + " ");
3751 switchTeamIndexMap[(int)menuItems.size()-1] = CREATE_NEW_TEAM;
3752 }
3753 menuItems.push_back(" " + lang.getString("Cancel") + " ");
3754 switchTeamIndexMap[(int)menuItems.size()-1] = CANCEL_SWITCH_TEAM;
3755
3756 popupMenuSwitchTeams.setW(100);
3757 popupMenuSwitchTeams.setH(100);
3758 popupMenuSwitchTeams.init(" " + lang.getString("SwitchTeams") + " ",menuItems);
3759 popupMenuSwitchTeams.setEnabled(true);
3760 popupMenuSwitchTeams.setVisible(true);
3761 }
3762 else if(result.first == disconnectPlayerPopupMenuIndex) {
3763 Lang &lang= Lang::getInstance();
3764
3765 NetworkManager &networkManager= NetworkManager::getInstance();
3766 NetworkRole role = networkManager.getNetworkRole();
3767 ServerInterface *serverInterface = NULL;
3768 if(role == nrServer) {
3769 serverInterface = dynamic_cast<ServerInterface *>(networkManager.getServerInterface());
3770 }
3771 disconnectPlayerIndexMap.clear();
3772 std::vector<string> menuItems;
3773 for(unsigned int i = 0; i < (unsigned int)world.getFactionCount(); ++i) {
3774 Faction *faction = world.getFaction(i);
3775
3776 //printf("faction->getPersonalityType() = %d index [%d,%d] control [%d] networkstatus [%d]\n",faction->getPersonalityType(),world.getThisFaction()->getIndex(),faction->getIndex(),faction->getControlType(),this->gameSettings.getNetworkPlayerStatuses(i));
3777
3778 bool isSlotJoinInProgressClient = false;
3779 if(serverInterface != NULL) {
3780
3781 MutexSafeWrapper safeMutex(serverInterface->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
3782 ConnectionSlot *slot = serverInterface->getSlot(faction->getStartLocationIndex(),false);
3783 if(slot != NULL && slot->getConnectHasHandshaked() == true &&
3784 slot->getCurrentFrameCount() <= 0) {
3785 isSlotJoinInProgressClient = true;
3786 }
3787 }
3788
3789 //printf("isSlotJoinInProgressClient: %d [%d] [%d][%d] [%d] [%d] [%d]\n",
3790 // isSlotJoinInProgressClient,faction->getPersonalityType(),faction->getIndex(),world.getThisFaction()->getIndex(),faction->getControlType(),this->gameSettings.getNetworkPlayerStatuses(i),i);
3791
3792 if(isSlotJoinInProgressClient == true ||
3793 (faction->getPersonalityType() != fpt_Observer &&
3794 world.getThisFaction()->getIndex() != faction->getIndex() &&
3795 faction->getControlType() == ctNetwork &&
3796 this->gameSettings.getNetworkPlayerStatuses(i) != npst_Disconnected)) {
3797
3798 char szBuf[8096]="";
3799 if(lang.hasString("DisconnectNetorkPlayerIndex") == true) {
3800 snprintf(szBuf,8096,(" " + lang.getString("DisconnectNetorkPlayerIndex") + " ").c_str(),faction->getIndex()+1,this->gameSettings.getNetworkPlayerName(i).c_str());
3801 }
3802 else {
3803 snprintf(szBuf,8096," Disconnect player #%d - %s: ",faction->getIndex()+1,this->gameSettings.getNetworkPlayerName(i).c_str());
3804 }
3805
3806 menuItems.push_back(szBuf);
3807
3808 //disconnectPlayerIndexMap[menuItems.size()-1] = faction->getStartLocationIndex();
3809 disconnectPlayerIndexMap[(int)menuItems.size()-1] = faction->getIndex();
3810 }
3811 }
3812
3813 menuItems.push_back(" " + lang.getString("Cancel") + " ");
3814 disconnectPlayerIndexMap[(int)menuItems.size()-1] = CANCEL_DISCONNECT_PLAYER;
3815
3816 popupMenuDisconnectPlayer.setW(100);
3817 popupMenuDisconnectPlayer.setH(100);
3818 popupMenuDisconnectPlayer.init(" " + lang.getString("DisconnectNetorkPlayer") + " ",menuItems);
3819 popupMenuDisconnectPlayer.setEnabled(true);
3820 popupMenuDisconnectPlayer.setVisible(true);
3821 }
3822 else if(result.first == keyboardSetupPopupMenuIndex) {
3823 MainMenu *newMenu = new MainMenu(program); // open keyboard shortcuts setup screen
3824 currentUIState = newMenu;
3825 Renderer &renderer= Renderer::getInstance();
3826 renderer.setCustom3dMenu(newMenu);
3827 //currentUIState->load();
3828 currentUIState->init();
3829
3830 // open keyboard shortcuts setup screen
3831 newMenu->setState(new MenuStateKeysetup(program, newMenu, ¤tUIState));
3832 }
3833 else if(result.first == pauseGamePopupMenuIndex) {
3834 //this->setPaused(!paused);
3835 //printf("popup paused = %d\n",paused);
3836
3837 bool allowAdminMenuItems = false;
3838 NetworkRole role = networkManager.getNetworkRole();
3839 if(role == nrServer) {
3840 allowAdminMenuItems = true;
3841 }
3842 else if(role == nrClient) {
3843 ClientInterface *clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
3844
3845 if(clientInterface != NULL &&
3846 gameSettings.getMasterserver_admin() == clientInterface->getSessionKey()) {
3847 allowAdminMenuItems = true;
3848 }
3849 }
3850
3851 if(allowAdminMenuItems) {
3852 if(getPaused() == false) {
3853 commander.tryPauseGame(false,false);
3854 }
3855 else {
3856 commander.tryResumeGame(false,false);
3857 }
3858 }
3859 }
3860 else if(result.first == saveGamePopupMenuIndex){
3861 saveGame();
3862 }
3863 //else if(result.first == markCellPopupMenuIndex) {
3864 // startMarkCell();
3865 //}
3866 //else if(result.first == unmarkCellPopupMenuIndex) {
3867 // isUnMarkCellEnabled = true;
3868 //}
3869 }
3870 else if(popupMenuSwitchTeams.mouseClick(x, y)) {
3871 //popupMenuSwitchTeams
3872 std::pair<int,string> result = popupMenuSwitchTeams.mouseClickedMenuItem(x, y);
3873 //printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first);
3874
3875 popupMenuSwitchTeams.setEnabled(false);
3876 popupMenuSwitchTeams.setVisible(false);
3877
3878 //bool isNetworkGame = this->gameSettings.isNetworkGame();
3879
3880 int teamIndex = switchTeamIndexMap[result.first];
3881 switch(teamIndex) {
3882 case CREATE_NEW_TEAM:
3883 {
3884 int newTeam = getFirstUnusedTeamNumber();
3885 //if(isNetworkGame == true) {
3886 const Faction *faction = world.getThisFaction();
3887 commander.trySwitchTeam(faction,newTeam);
3888 //}
3889 //else {
3890 // const Faction *faction = world.getThisFaction();
3891 // commander.trySwitchTeam(faction,newTeam);
3892 //}
3893 }
3894 break;
3895 case CANCEL_SWITCH_TEAM:
3896 break;
3897 default:
3898 //if(isNetworkGame == true) {
3899 const Faction *faction = world.getThisFaction();
3900 commander.trySwitchTeam(faction,teamIndex);
3901 //}
3902 //else {
3903 // const Faction *faction = world.getThisFaction();
3904 // commander.trySwitchTeam(faction,teamIndex);
3905 //}
3906
3907 break;
3908 }
3909 }
3910 else if(popupMenuDisconnectPlayer.mouseClick(x, y)) {
3911 //popupMenuSwitchTeams
3912 std::pair<int,string> result = popupMenuDisconnectPlayer.mouseClickedMenuItem(x, y);
3913 //printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first);
3914
3915 popupMenuDisconnectPlayer.setEnabled(false);
3916 popupMenuDisconnectPlayer.setVisible(false);
3917
3918 //bool isNetworkGame = this->gameSettings.isNetworkGame();
3919
3920 //int playerIndex = disconnectPlayerIndexMap[result.first];
3921 int factionIndex = disconnectPlayerIndexMap[result.first];
3922 switch(factionIndex) {
3923 case CANCEL_DISCONNECT_PLAYER:
3924 break;
3925 default:
3926 // if(isNetworkGame == true) {
3927 // const Faction *faction = world.getThisFaction();
3928 // commander.trySwitchTeam(faction,teamIndex);
3929 // }
3930 // else {
3931 // const Faction *faction = world.getThisFaction();
3932 // commander.trySwitchTeam(faction,teamIndex);
3933 // }
3934
3935
3936 GameSettings *settings = world.getGameSettingsPtr();
3937 Lang &lang= Lang::getInstance();
3938
3939 char szBuf[8096]="";
3940 if(lang.hasString("DisconnectNetorkPlayerIndexConfirm") == true) {
3941 snprintf(szBuf,8096,(" " + lang.getString("DisconnectNetorkPlayerIndexConfirm") + " ").c_str(),factionIndex+1,settings->getNetworkPlayerName(factionIndex).c_str());
3942 }
3943 else {
3944 snprintf(szBuf,8096," Confirm disconnection for player #%d - %s? ",factionIndex+1,settings->getNetworkPlayerName(factionIndex).c_str());
3945 }
3946
3947 disconnectPlayerConfirmMessageBox.setText(szBuf);
3948 disconnectPlayerConfirmMessageBox.init(lang.getString("Yes"), lang.getString("No"));
3949 disconnectPlayerConfirmMessageBox.setEnabled(true);
3950
3951 playerIndexDisconnect = world.getFaction(factionIndex)->getStartLocationIndex();
3952
3953 GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
3954 if(gameNetworkInterface != NULL) {
3955 Lang &lang= Lang::getInstance();
3956 const vector<string> languageList = settings->getUniqueNetworkPlayerLanguages();
3957 for(unsigned int i = 0; i < (unsigned int)languageList.size(); ++i) {
3958 char szMsg[8096]="";
3959 if(lang.hasString("DisconnectNetorkPlayerIndexConfirmed",languageList[i]) == true) {
3960 snprintf(szMsg,8096,lang.getString("DisconnectNetorkPlayerIndexConfirmed",languageList[i]).c_str(),factionIndex+1,settings->getNetworkPlayerName(factionIndex).c_str());
3961 }
3962 else {
3963 snprintf(szMsg,8096,"Notice - Admin is warning to disconnect player #%d - %s!",factionIndex+1,settings->getNetworkPlayerName(factionIndex).c_str());
3964 }
3965 bool localEcho = lang.isLanguageLocal(languageList[i]);
3966 gameNetworkInterface->sendTextMessage(szMsg,-1, localEcho,languageList[i]);
3967 }
3968
3969 sleep(10);
3970 }
3971
3972 break;
3973 }
3974 }
3975
3976 if(switchTeamConfirmMessageBox.getEnabled() == true) {
3977 int button= -1;
3978 if(switchTeamConfirmMessageBox.mouseClick(x,y,button)) {
3979 switchTeamConfirmMessageBox.setEnabled(false);
3980
3981 SwitchTeamVote *vote = world.getThisFactionPtr()->getSwitchTeamVote(world.getThisFaction()->getCurrentSwitchTeamVoteFactionIndex());
3982 vote->voted = true;
3983 vote->allowSwitchTeam = (button == 0);
3984
3985 const Faction *faction = world.getThisFaction();
3986 commander.trySwitchTeamVote(faction,vote);
3987 }
3988 }
3989 else if(disconnectPlayerConfirmMessageBox.getEnabled() == true) {
3990 int button= -1;
3991 if(disconnectPlayerConfirmMessageBox.mouseClick(x,y,button)) {
3992 disconnectPlayerConfirmMessageBox.setEnabled(false);
3993
3994 if(button == 0) {
3995 const Faction *faction = world.getThisFaction();
3996 commander.tryDisconnectNetworkPlayer(faction,playerIndexDisconnect);
3997 }
3998 }
3999 }
4000
4001 //scrip message box, only if the exit box is not enabled
4002 if( mainMessageBox.getEnabled() == false &&
4003 errorMessageBox.getEnabled() == false &&
4004 scriptManager.getMessageBox()->getEnabled()) {
4005 int button= 0;
4006 if(scriptManager.getMessageBox()->mouseClick(x, y, button)){
4007 scriptManager.onMessageBoxOk();
4008 messageBoxClick= true;
4009 }
4010 }
4011
4012 //minimap panel
4013 if(messageBoxClick == false) {
4014 if(metrics.isInMinimap(x, y)){
4015 int xm= x - metrics.getMinimapX();
4016 int ym= y - metrics.getMinimapY();
4017 int xCell= static_cast<int>(xm * (static_cast<float>(map->getW()) / metrics.getMinimapW()));
4018 int yCell= static_cast<int>(map->getH() - ym * (static_cast<float>(map->getH()) / metrics.getMinimapH()));
4019
4020 if(map->isInside(xCell, yCell) && map->isInsideSurface(map->toSurfCoords(Vec2i(xCell,yCell)))) {
4021 if(gui.isSelectingPos()){
4022 gui.mouseDownLeftGraphics(xCell, yCell, true);
4023 }
4024 else
4025 {
4026 if(!setMarker) {
4027 cameraDragAllowed=true;
4028 gameCamera.setPos(Vec2f(static_cast<float>(xCell), static_cast<float>(yCell)));
4029 }
4030 }
4031
4032 if(setMarker) {
4033 Vec2i surfaceCellPos = map->toSurfCoords(Vec2i(xCell,yCell));
4034 SurfaceCell *sc = map->getSurfaceCell(surfaceCellPos);
4035 Vec3f vertex = sc->getVertex();
4036 Vec2i targetPos(vertex.x,vertex.z);
4037
4038 MarkedCell mc(targetPos,world.getThisFaction(),"none",world.getThisFaction()->getStartLocationIndex());
4039 addOrReplaceInHighlightedCells(mc);
4040
4041 GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
4042 gameNetworkInterface->sendHighlightCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex());
4043 }
4044
4045
4046 if(originalIsMarkCellEnabled == true && isMarkCellEnabled == true) {
4047 Vec2i surfaceCellPos = map->toSurfCoords(Vec2i(xCell,yCell));
4048 SurfaceCell *sc = map->getSurfaceCell(surfaceCellPos);
4049 Vec3f vertex = sc->getVertex();
4050 Vec2i targetPos(vertex.x,vertex.z);
4051
4052 MarkedCell mc(targetPos,world.getThisFaction(),"placeholder for note",world.getThisFaction()->getStartLocationIndex());
4053
4054 //GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
4055 //gameNetworkInterface->sendMarkCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex(),mc.getNote());
4056
4057 //printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size());
4058
4059 isMarkCellEnabled = false;
4060 cellMarkedData = mc;
4061 cellMarkedPos = surfaceCellPos;
4062 isMarkCellTextEnabled = true;
4063 chatManager.switchOnEdit(this,500);
4064
4065 Renderer &renderer= Renderer::getInstance();
4066 //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos);
4067 renderer.forceQuadCacheUpdate();
4068 }
4069 if(originalIsUnMarkCellEnabled == true && isUnMarkCellEnabled == true) {
4070 Vec2i surfaceCellPos = map->toSurfCoords(Vec2i(xCell,yCell));
4071 SurfaceCell *sc = map->getSurfaceCell(surfaceCellPos);
4072 Vec3f vertex = sc->getVertex();
4073 Vec2i targetPos(vertex.x,vertex.z);
4074
4075 // if(mapMarkedCellList.find(surfaceCellPos) != mapMarkedCellList.end()) {
4076 // MarkedCell mc = mapMarkedCellList[surfaceCellPos];
4077 // if(mc.getFaction() == world.getThisFaction()) {
4078 // mapMarkedCellList.erase(surfaceCellPos);
4079 // GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
4080 // gameNetworkInterface->sendUnMarkCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex());
4081 // }
4082 // }
4083
4084 isUnMarkCellEnabled = false;
4085
4086 removeCellMarker(surfaceCellPos, world.getThisFaction());
4087 //printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size());
4088
4089 Renderer &renderer= Renderer::getInstance();
4090 //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos);
4091 renderer.forceQuadCacheUpdate();
4092 }
4093 }
4094 }
4095 //display panel
4096 else if(metrics.isInDisplay(x, y) && !gui.isSelectingPos()) {
4097 int xd= x - metrics.getDisplayX();
4098 int yd= y - metrics.getDisplayY();
4099 if(gui.mouseValid(xd, yd)) {
4100 gui.mouseDownLeftDisplay(xd, yd);
4101 }
4102 else {
4103 gui.mouseDownLeftGraphics(x, y, false);
4104 }
4105 }
4106 //graphics panel
4107 else {
4108 gui.mouseDownLeftGraphics(x, y, false);
4109
4110 if(setMarker) {
4111 Vec2i targetPos;
4112 Vec2i screenPos(x,y-60);
4113 targetPos=getMouseCellPos();
4114 //Vec2i surfaceCellPos = map->toSurfCoords(targetPos);
4115
4116
4117 MarkedCell mc(targetPos,world.getThisFaction(),"none",world.getThisFaction()->getStartLocationIndex());
4118 addOrReplaceInHighlightedCells(mc);
4119
4120 GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
4121 gameNetworkInterface->sendHighlightCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex());
4122 }
4123
4124 if(originalIsMarkCellEnabled == true && isMarkCellEnabled == true) {
4125 Vec2i targetPos;
4126 Vec2i screenPos(x,y-60);
4127 targetPos=getMouseCellPos();
4128 Vec2i surfaceCellPos = map->toSurfCoords(targetPos);
4129
4130 MarkedCell mc(targetPos,world.getThisFaction(),"placeholder for note",world.getThisFaction()->getStartLocationIndex());
4131
4132 //printf("#2 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size());
4133
4134 isMarkCellEnabled = false;
4135 cellMarkedData = mc;
4136 cellMarkedPos = surfaceCellPos;
4137 isMarkCellTextEnabled = true;
4138 chatManager.switchOnEdit(this,500);
4139
4140 //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos);
4141 Renderer::getInstance().forceQuadCacheUpdate();
4142 }
4143
4144 if(originalIsUnMarkCellEnabled == true && isUnMarkCellEnabled == true) {
4145 Vec2i targetPos;
4146 Vec2i screenPos(x,y-35);
4147 targetPos=getMouseCellPos();
4148 Vec2i surfaceCellPos = map->toSurfCoords(targetPos);
4149
4150 // if(mapMarkedCellList.find(surfaceCellPos) != mapMarkedCellList.end()) {
4151 // MarkedCell mc = mapMarkedCellList[surfaceCellPos];
4152 // if(mc.getFaction() == world.getThisFaction()) {
4153 // mapMarkedCellList.erase(surfaceCellPos);
4154 // GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
4155 // gameNetworkInterface->sendUnMarkCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex());
4156 // }
4157 // }
4158
4159 isUnMarkCellEnabled = false;
4160 removeCellMarker(surfaceCellPos, world.getThisFaction());
4161 //printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size());
4162
4163 //Renderer &renderer= Renderer::getInstance();
4164 //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos);
4165 Renderer::getInstance().forceQuadCacheUpdate();
4166 }
4167 }
4168 }
4169
4170 //exit message box, has to be the last thing to do in this function
4171 if(errorMessageBox.getEnabled() == true) {
4172 if(errorMessageBox.mouseClick(x, y)) {
4173 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
4174 //close message box
4175 errorMessageBox.setEnabled(false);
4176 }
4177 }
4178 if(mainMessageBox.getEnabled()){
4179 int button= 0;
4180 if(mainMessageBox.mouseClick(x, y, button)) {
4181 if(button==0) {
4182 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
4183 if(networkManager.getGameNetworkInterface() != NULL) {
4184 networkManager.getGameNetworkInterface()->quitGame(true);
4185 }
4186 quitTriggeredIndicator = true;
4187 return;
4188 }
4189 else {
4190 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
4191 //close message box
4192 mainMessageBox.setEnabled(false);
4193 }
4194 }
4195 }
4196 }
4197 catch(const exception &ex) {
4198 char szBuf[8096]="";
4199 snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
4200
4201 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
4202 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
4203
4204 NetworkManager &networkManager= NetworkManager::getInstance();
4205 if(networkManager.getGameNetworkInterface() != NULL) {
4206 GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
4207 networkInterface->sendTextMessage(szBuf,-1,true,"");
4208 sleep(10);
4209 networkManager.getGameNetworkInterface()->quitGame(true);
4210 }
4211 ErrorDisplayMessage(ex.what(),true);
4212 }
4213 }
4214
4215 void Game::mouseDownRight(int x, int y) {
4216 if(this->masterserverMode == true) {
4217 return;
4218 }
4219
4220 if(currentUIState != NULL) {
4221 currentUIState->mouseDownRight(x, y);
4222 return;
4223 }
4224
4225 try {
4226 if(gameStarted == false || totalRenderFps <= 0) {
4227 Logger::getInstance().handleMouseClick(x, y);
4228 return;
4229 }
4230
4231 Map *map= world.getMap();
4232 const Metrics &metrics= Metrics::getInstance();
4233
4234 if(metrics.isInMinimap(x, y) ){
4235 int xm= x - metrics.getMinimapX();
4236 int ym= y - metrics.getMinimapY();
4237 int xCell= static_cast<int>(xm * (static_cast<float>(map->getW()) / metrics.getMinimapW()));
4238 int yCell= static_cast<int>(map->getH() - ym * (static_cast<float>(map->getH()) / metrics.getMinimapH()));
4239
4240 if(map->isInside(xCell, yCell) && map->isInsideSurface(map->toSurfCoords(Vec2i(xCell,yCell)))) {
4241 gui.mouseDownRightGraphics(xCell, yCell,true);
4242 }
4243 }
4244 else {
4245 Vec2i targetPos;
4246 Vec2i screenPos(x,y);
4247 targetPos=getMouseCellPos();
4248 if(isValidMouseCellPos() == true &&
4249 map->isInsideSurface(map->toSurfCoords(targetPos)) == true) {
4250 gui.mouseDownRightGraphics(x, y,false);
4251 }
4252 }
4253 }
4254 catch(const exception &ex) {
4255 char szBuf[8096]="";
4256 snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s] x = %d y = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what(),x,y);
4257
4258 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
4259 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
4260
4261 NetworkManager &networkManager= NetworkManager::getInstance();
4262 if(networkManager.getGameNetworkInterface() != NULL) {
4263 GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
4264 networkInterface->sendTextMessage(szBuf,-1,true,"");
4265 sleep(10);
4266 networkManager.getGameNetworkInterface()->quitGame(true);
4267 }
4268 ErrorDisplayMessage(ex.what(),true);
4269 }
4270 }
4271
4272 void Game::mouseUpCenter(int x, int y) {
4273 if(this->masterserverMode == true) {
4274 return;
4275 }
4276
4277 if(gameStarted == false || totalRenderFps <= 0) {
4278 return;
4279 }
4280
4281 if(currentUIState != NULL) {
4282 currentUIState->mouseUpCenter(x, y);
4283 return;
4284 }
4285
4286 if(mouseMoved == false) {
4287 gameCamera.setState(GameCamera::sGame);
4288 }
4289 else {
4290 mouseMoved = false;
4291 }
4292 }
4293
4294 void Game::mouseUpLeft(int x, int y) {
4295 if(this->masterserverMode == true) {
4296 return;
4297 }
4298
4299 try {
4300 if(gameStarted == false || totalRenderFps <= 0) {
4301 return;
4302 }
4303
4304 if(currentUIState != NULL) {
4305 currentUIState->mouseUpLeft(x, y);
4306 return;
4307 }
4308
4309 gui.mouseUpLeftGraphics(x, y);
4310 }
4311 catch(const exception &ex) {
4312 char szBuf[8096]="";
4313 snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
4314
4315 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
4316 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
4317
4318 NetworkManager &networkManager= NetworkManager::getInstance();
4319 if(networkManager.getGameNetworkInterface() != NULL) {
4320 GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
4321 networkInterface->sendTextMessage(szBuf,-1,true,"");
4322 sleep(10);
4323 networkManager.getGameNetworkInterface()->quitGame(true);
4324 }
4325 ErrorDisplayMessage(ex.what(),true);
4326 }
4327 }
4328
4329 void Game::mouseDoubleClickLeft(int x, int y) {
4330 if(this->masterserverMode == true) {
4331 return;
4332 }
4333
4334 try {
4335 if(gameStarted == false || totalRenderFps <= 0) {
4336 return;
4337 }
4338 if(currentUIState != NULL) {
4339 currentUIState->mouseDoubleClickLeft(x, y);
4340 return;
4341 }
4342
4343 const Metrics &metrics= Metrics::getInstance();
4344
4345 if(metrics.isInMinimap(x, y)){
4346 // no double click on minimap
4347 }
4348 else {
4349 //display panel
4350 if(metrics.isInDisplay(x, y) && !gui.isSelectingPos()) {
4351 int xd= x - metrics.getDisplayX();
4352 int yd= y - metrics.getDisplayY();
4353 if(gui.mouseValid(xd, yd)){
4354 return;
4355 }
4356 }
4357 //graphics panel
4358 gui.mouseDoubleClickLeftGraphics(x, y);
4359 }
4360 }
4361 catch(const exception &ex) {
4362 char szBuf[8096]="";
4363 snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
4364
4365 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
4366 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
4367
4368 NetworkManager &networkManager= NetworkManager::getInstance();
4369 if(networkManager.getGameNetworkInterface() != NULL) {
4370 GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
4371 networkInterface->sendTextMessage(szBuf,-1,true,"");
4372 sleep(10);
4373 networkManager.getGameNetworkInterface()->quitGame(true);
4374 }
4375 ErrorDisplayMessage(ex.what(),true);
4376 }
4377 }
4378
4379 void Game::mouseMove(int x, int y, const MouseState *ms) {
4380 if(this->masterserverMode == true) {
4381 return;
4382 }
4383
4384 try {
4385 if(gameStarted == false || totalRenderFps <= 0) {
4386 return;
4387 }
4388 if(currentUIState != NULL) {
4389 currentUIState->mouseMove(x, y, ms);
4390 return;
4391 }
4392
4393 popupMenu.mouseMove(x, y);
4394 popupMenuSwitchTeams.mouseMove(x, y);
4395 popupMenuDisconnectPlayer.mouseMove(x, y);
4396
4397 const Metrics &metrics = Metrics::getInstance();
4398
4399 mouseX = x;
4400 mouseY = y;
4401
4402 if (ms->get(mbCenter)) {
4403 mouseMoved = true;
4404 if(currentCameraFollowUnit == NULL) {
4405 float ymult = 0.2f;
4406 float xmult = 0.2f;
4407
4408 Vec2i oldPos = ::Shared::Platform::Window::getOldMousePos();
4409 int oldx= (oldPos.x * metrics.getVirtualW() / metrics.getScreenW());
4410 int oldy= ((metrics.getScreenH()-oldPos.y) * metrics.getVirtualH() / metrics.getScreenH());
4411 lastMousePos.x=oldx;
4412 lastMousePos.y=oldy;
4413 gameCamera.transitionVH(-(y - oldy) * ymult, (oldx - x) * xmult);
4414 }
4415 mouseX=lastMousePos.x;
4416 mouseY=lastMousePos.y;
4417 ::Shared::Platform::Window::revertMousePos();
4418
4419 return;
4420 }
4421 else if(currentCameraFollowUnit==NULL) {
4422 //if(Window::isKeyDown() == false)
4423 if(!camLeftButtonDown && !camRightButtonDown && !camUpButtonDown && !camDownButtonDown)
4424 {
4425 if(ms->get(mbLeft) && metrics.isInMinimap(x, y)) {
4426 int xm= x - metrics.getMinimapX();
4427 int ym= y - metrics.getMinimapY();
4428
4429 Map *map= world.getMap();
4430 int xCell= static_cast<int>(xm * (static_cast<float>(map->getW()) / metrics.getMinimapW()));
4431 int yCell= static_cast<int>(map->getH() - ym * (static_cast<float>(map->getH()) / metrics.getMinimapH()));
4432
4433 if(map->isInside(xCell, yCell) && map->isInsideSurface(map->toSurfCoords(Vec2i(xCell,yCell)))) {
4434 if(gui.isSelectingPos()){
4435 gui.mouseDownLeftGraphics(xCell, yCell, true);
4436 }
4437 else
4438 {
4439 if(cameraDragAllowed == true) {
4440 gameCamera.setPos(Vec2f(static_cast<float>(xCell), static_cast<float>(yCell)));
4441 }
4442 }
4443 }
4444 }
4445 else {
4446 bool mouseMoveScrollsWorld = Config::getInstance().getBool("MouseMoveScrollsWorld","true");
4447 if(mouseMoveScrollsWorld == true) {
4448 if (y < 10) {
4449 gameCamera.setMoveZ(-scrollSpeed);
4450 }
4451 else if (y > metrics.getVirtualH() - 10) {
4452 gameCamera.setMoveZ(scrollSpeed);
4453 }
4454 else {
4455 gameCamera.setMoveZ(0);
4456 }
4457
4458 if (x < 10) {
4459 gameCamera.setMoveX(-scrollSpeed);
4460 }
4461 else if (x > metrics.getVirtualW() - 10) {
4462 gameCamera.setMoveX(scrollSpeed);
4463 }
4464 else {
4465 gameCamera.setMoveX(0);
4466 }
4467 }
4468 }
4469 }
4470
4471 if(switchTeamConfirmMessageBox.getEnabled() == true) {
4472 switchTeamConfirmMessageBox.mouseMove(x,y);
4473 }
4474
4475 if(disconnectPlayerConfirmMessageBox.getEnabled() == true) {
4476 disconnectPlayerConfirmMessageBox.mouseMove(x,y);
4477 }
4478
4479 if (mainMessageBox.getEnabled()) {
4480 mainMessageBox.mouseMove(x, y);
4481 }
4482 if (errorMessageBox.getEnabled()) {
4483 errorMessageBox.mouseMove(x, y);
4484 }
4485 if (scriptManager.getMessageBox()->getEnabled()) {
4486 scriptManager.getMessageBox()->mouseMove(x, y);
4487 }
4488 //else if (saveBox) {
4489 // saveBox->mouseMove(x, y);
4490 //} else {
4491 // //graphics
4492 gui.mouseMoveGraphics(x, y);
4493 //}
4494 }
4495
4496 //display
4497 if ( !gui.isSelecting() && !gui.isSelectingPos()) {
4498 if (!gui.isSelectingPos()) {
4499 if(metrics.isInDisplay(x, y)){
4500 gui.mouseMoveDisplay(x - metrics.getDisplayX(), y - metrics.getDisplayY());
4501 }
4502 else {
4503 gui.mouseMoveOutsideDisplay();
4504 }
4505 }
4506 }
4507
4508 lastMousePos.x = mouseX;
4509 lastMousePos.y = mouseY;
4510
4511 Renderer &renderer= Renderer::getInstance();
4512 renderer.ccomputePosition(Vec2i(mouseX, mouseY), mouseCellPos);
4513 }
4514 catch(const exception &ex) {
4515 char szBuf[8096]="";
4516 snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
4517
4518 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
4519 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
4520
4521 NetworkManager &networkManager= NetworkManager::getInstance();
4522 if(networkManager.getGameNetworkInterface() != NULL) {
4523 GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
4524 networkInterface->sendTextMessage(szBuf,-1,true,"");
4525 sleep(10);
4526 networkManager.getGameNetworkInterface()->quitGame(true);
4527 }
4528 ErrorDisplayMessage(ex.what(),true);
4529 }
4530 }
4531
4532 bool Game::isValidMouseCellPos() const{
4533 if(world.getMap() == NULL){
4534 return false;
4535 }
4536 else {
4537 return world.getMap()->isInside(mouseCellPos);
4538 }
4539 }
4540
4541 void Game::eventMouseWheel(int x, int y, int zDelta) {
4542 if(this->masterserverMode == true) {
4543 return;
4544 }
4545
4546 if(currentUIState != NULL) {
4547 currentUIState->eventMouseWheel(x, y, zDelta);
4548 return;
4549 }
4550
4551 try {
4552 gameCamera.zoom((float)zDelta / 60.0f);
4553 }
4554 catch(const exception &ex) {
4555 char szBuf[8096]="";
4556 snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
4557
4558 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
4559 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
4560
4561 NetworkManager &networkManager= NetworkManager::getInstance();
4562 if(networkManager.getGameNetworkInterface() != NULL) {
4563 GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
4564 networkInterface->sendTextMessage(szBuf,-1,true,"");
4565 sleep(10);
4566 networkManager.getGameNetworkInterface()->quitGame(true);
4567 }
4568 ErrorDisplayMessage(ex.what(),true);
4569 }
4570 }
4571
4572 void Game::startCameraFollowUnit() {
4573 Selection *selection= gui.getSelectionPtr();
4574 if(selection->getCount() == 1) {
4575 Unit *currentUnit = selection->getUnitPtr(0);
4576 if(currentUnit != NULL) {
4577 currentCameraFollowUnit = currentUnit;
4578 getGameCameraPtr()->setState(GameCamera::sUnit);
4579 getGameCameraPtr()->setPos(currentCameraFollowUnit->getCurrMidHeightVector());
4580
4581 int rotation=currentCameraFollowUnit->getRotation();
4582 getGameCameraPtr()->stop();
4583 getGameCameraPtr()->rotateToVH(0.0f,(540-rotation)%360);
4584 getGameCameraPtr()->setHAng((540-rotation)%360);
4585 getGameCameraPtr()->setVAng(0.0f);
4586 }
4587 }
4588 else {
4589 if(currentCameraFollowUnit != NULL) {
4590 currentCameraFollowUnit = NULL;
4591 }
4592 }
4593 }
4594
4595 bool Game::textInput(std::string text) {
4596 if(chatManager.getEditEnabled() == true) {
4597 return chatManager.textInput(text);
4598 }
4599 return false;
4600 }
4601
4602 bool Game::sdlKeyDown(SDL_KeyboardEvent key) {
4603 if(this->masterserverMode == true) {
4604 return false;
4605 }
4606 if(gameStarted == false || totalRenderFps <= 0) {
4607 return false;
4608 }
4609
4610 if(chatManager.getEditEnabled() == true) {
4611 return false;
4612 }
4613 Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
4614 //group
4615 for(int idx = 1; idx <= Selection::maxGroups; idx++) {
4616 string keyName = "GroupUnitsKey" + intToStr(idx);
4617
4618 SDL_Keycode groupHotKey = configKeys.getSDLKey(keyName.c_str());
4619 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] keyName [%s] group index = %d, key = [%c] [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,keyName.c_str(),idx,groupHotKey,groupHotKey);
4620
4621 //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("input.keysym.mod = %d groupHotKey = %d key = %d (%d) [%s] isgroup = %d\n",key.keysym.mod,groupHotKey,key.keysym.sym,key.keysym.unicode,keyName.c_str(),isKeyPressed(groupHotKey,key));
4622 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("input.keysym.mod = %d groupHotKey = %d key = (%d) [%s] isgroup = %d\n",key.keysym.mod,groupHotKey,key.keysym.sym,keyName.c_str(),isKeyPressed(groupHotKey,key));
4623 //printf(" group key check %d scancode:%d sym:%d groupHotKey=%d \n",idx,key.keysym.scancode,key.keysym.sym,groupHotKey);
4624 if(key.keysym.sym==groupHotKey){
4625 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
4626 //printf("IS GROUP KEY %d scancode:%d sym:%d groupHotKey=%d \n",idx,key.keysym.scancode,key.keysym.sym,groupHotKey);
4627 gui.groupKey(idx-1);
4628 return true;
4629 }
4630 }
4631 return false;
4632 }
4633
4634 void Game::keyDown(SDL_KeyboardEvent key) {
4635 if(this->masterserverMode == true) {
4636 return;
4637 }
4638
4639 //printf("In game checking keypress for key [%d]\n",key.keysym.sym);
4640
4641 try {
4642 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c] [%d] gameStarted [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,key.keysym.sym,key.keysym.sym, gameStarted);
4643 if(gameStarted == false || totalRenderFps <= 0) {
4644 return;
4645 }
4646 if(currentUIState != NULL) {
4647 currentUIState->keyDown(key);
4648 return;
4649 }
4650
4651 Lang &lang= Lang::getInstance();
4652 bool formerChatState=chatManager.getEditEnabled();
4653 //send key to the chat manager
4654 chatManager.keyDown(key);
4655
4656 if( formerChatState==false && chatManager.getEditEnabled()) {
4657 camUpButtonDown= false;
4658 camDownButtonDown = false;
4659 camLeftButtonDown = false;
4660 camRightButtonDown = false;
4661
4662 gameCamera.stopMove();
4663 }
4664
4665 //printf("GAME KEYDOWN #1\n");
4666
4667 if(chatManager.getEditEnabled() == false) {
4668 //printf("GAME KEYDOWN #2\n");
4669 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%d - %c]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,key.keysym.sym,key.keysym.sym);
4670
4671 Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
4672 //if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] key = [%d - %c] pausegame [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,key,key,configKeys.getCharKey("PauseGame"));
4673
4674 //printf("SDL [%d] key [%d][%d]\n",configKeys.getSDLKey("SetMarker"),key.keysym.unicode,key.keysym.sym);
4675 bool setMarkerKeyAllowsModifier = false;
4676 if( configKeys.getSDLKey("SetMarker") == SDLK_RALT ||
4677 configKeys.getSDLKey("SetMarker") == SDLK_LALT) {
4678 setMarkerKeyAllowsModifier = true;
4679 }
4680
4681 //printf("In game checking keypress for key [%d] camera left [%d]\n",key.keysym.sym,configKeys.getSDLKey("CameraModeLeft"));
4682
4683 if(isKeyPressed(configKeys.getSDLKey("RenderInGamePerformance"),key, false) == true) {
4684 renderInGamePerformance = !renderInGamePerformance;
4685
4686 Config::getInstance().setBool("PerformanceWarningEnabled",renderInGamePerformance, true);
4687 }
4688 //if(key == configKeys.getCharKey("RenderNetworkStatus")) {
4689 else if(isKeyPressed(configKeys.getSDLKey("RenderNetworkStatus"),key, false) == true) {
4690 renderNetworkStatus= !renderNetworkStatus;
4691 }
4692 //else if(key == configKeys.getCharKey("ShowFullConsole")) {
4693 else if(isKeyPressed(configKeys.getSDLKey("ShowFullConsole"),key, false) == true) {
4694 showFullConsole= true;
4695 }
4696 else if(isKeyPressed(configKeys.getSDLKey("SetMarker"),key, setMarkerKeyAllowsModifier) == true) {
4697 setMarker= true;
4698 }
4699 //else if(key == configKeys.getCharKey("TogglePhotoMode")) {
4700 else if(isKeyPressed(configKeys.getSDLKey("TogglePhotoMode"),key, false) == true) {
4701 photoModeEnabled = !photoModeEnabled;
4702 if( photoModeEnabled == true &&
4703 this->gameSettings.isNetworkGame() == false) {
4704 gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT);
4705 }
4706 else if(photoModeEnabled == false) {
4707 gameCamera.setMaxHeight(-1);
4708 }
4709
4710 }
4711 //Toggle Healthbars
4712 else if(isKeyPressed(configKeys.getSDLKey("ToggleHealthbars"),key, false) == true) {
4713 switch (healthbarMode) {
4714 case hbvUndefined:
4715 healthbarMode=hbvOff;
4716 console.addLine(lang.getString("Healthbar2")+": "+lang.getString("HealthbarsOff"));
4717 break;
4718 case hbvOff:
4719 healthbarMode=hbvAlways;
4720 console.addLine(lang.getString("Healthbar2")+": "+lang.getString("HealthbarsAlways"));
4721 break;
4722 case hbvAlways:
4723 healthbarMode=hbvIfNeeded;
4724 console.addLine(lang.getString("Healthbar2")+": "+lang.getString("HealthbarsIfNeeded"));
4725 break;
4726 case hbvIfNeeded:
4727 healthbarMode=hbvSelected;
4728 console.addLine(lang.getString("Healthbar2")+": "+lang.getString("HealthbarsSelected"));
4729 break;
4730 case hbvSelected:
4731 healthbarMode=hbvSelected | hbvIfNeeded;
4732 console.addLine(lang.getString("Healthbar2")+": "+lang.getString("HealthbarsSelectedOrNeeded"));
4733 break;
4734 case (hbvSelected | hbvIfNeeded):
4735 healthbarMode=hbvUndefined;
4736 console.addLine(lang.getString("Healthbar2")+": "+lang.getString("HealthbarsFactionDefault"));
4737 break;
4738 default:
4739 printf("In [%s::%s Line: %d] Toggle Healthbars Hotkey - Invalid Value. Setting to default.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
4740 healthbarMode=hbvUndefined;
4741 break;
4742 }
4743 }
4744 //Toggle music
4745 //else if(key == configKeys.getCharKey("ToggleMusic")) {
4746 else if(isKeyPressed(configKeys.getSDLKey("ToggleMusic"),key, false) == true) {
4747
4748 if(this->masterserverMode == false) {
4749 Config &config = Config::getInstance();
4750 StrSound *gameMusic = world.getThisFaction()->getType()->getMusic();
4751 if(gameMusic != NULL) {
4752 float configVolume = (config.getInt("SoundVolumeMusic") / 100.f);
4753 float currentVolume = gameMusic->getVolume();
4754 if(currentVolume > 0) {
4755 gameMusic->setVolume(0);
4756 console.addLine(lang.getString("GameMusic") + " " + lang.getString("Off"));
4757 }
4758 else {
4759 //If the config says zero, use the default music volume
4760 gameMusic->setVolume(configVolume ? configVolume : 0.9);
4761 console.addLine(lang.getString("GameMusic"));
4762 }
4763 }
4764 }
4765 }
4766 //move camera left
4767 //else if(key == configKeys.getCharKey("CameraModeLeft")) {
4768 else if(isKeyPressed(configKeys.getSDLKey("CameraModeLeft"),key, false) == true) {
4769 gameCamera.setMoveX(-1);
4770 camLeftButtonDown=true;
4771 }
4772 //move camera right
4773 //else if(key == configKeys.getCharKey("CameraModeRight")) {
4774 else if(isKeyPressed(configKeys.getSDLKey("CameraModeRight"),key, false) == true) {
4775 gameCamera.setMoveX(1);
4776 camRightButtonDown=true;
4777 }
4778 //move camera up
4779 //else if(key == configKeys.getCharKey("CameraModeUp")) {
4780 else if(isKeyPressed(configKeys.getSDLKey("CameraModeUp"),key, false) == true) {
4781 gameCamera.setMoveZ(1);
4782 camUpButtonDown=true;
4783 }
4784 //move camera down
4785 //else if(key == configKeys.getCharKey("CameraModeDown")) {
4786 else if(isKeyPressed(configKeys.getSDLKey("CameraModeDown"),key, false) == true) {
4787 gameCamera.setMoveZ(-1);
4788 camDownButtonDown=true;
4789 }
4790 //change camera mode
4791 //else if(key == configKeys.getCharKey("FreeCameraMode")) {
4792 else if(isKeyPressed(configKeys.getSDLKey("FreeCameraMode"),key, false) == true) {
4793 if(gameCamera.getState()==GameCamera::sFree)
4794 {
4795 gameCamera.setState(GameCamera::sGame);
4796 string stateString= gameCamera.getState()==GameCamera::sGame? lang.getString("GameCamera"): lang.getString("FreeCamera");
4797 console.addLine(lang.getString("CameraModeSet")+" "+ stateString);
4798 }
4799 else if(gameCamera.getState()==GameCamera::sGame)
4800 {
4801 gameCamera.setState(GameCamera::sFree);
4802 string stateString= gameCamera.getState()==GameCamera::sGame? lang.getString("GameCamera"): lang.getString("FreeCamera");
4803 console.addLine(lang.getString("CameraModeSet")+" "+ stateString);
4804 }
4805 //else ignore!
4806 }
4807 //reset camera mode to normal
4808 //else if(key == configKeys.getCharKey("ResetCameraMode")) {
4809 else if(isKeyPressed(configKeys.getSDLKey("ResetCameraMode"),key, false) == true) {
4810 if(currentCameraFollowUnit != NULL) {
4811 currentCameraFollowUnit = NULL;
4812 }
4813 gameCamera.setState(GameCamera::sGame);
4814 }
4815 //pause
4816 //else if(key == configKeys.getCharKey("PauseGame")) {
4817 else if(isKeyPressed(configKeys.getSDLKey("PauseGame"),key, false) == true) {
4818 //printf("Toggle pause paused = %d\n",paused);
4819 //setPaused(!paused);
4820
4821 bool allowAdminMenuItems = false;
4822 NetworkManager &networkManager= NetworkManager::getInstance();
4823 NetworkRole role = networkManager.getNetworkRole();
4824 if(role == nrServer) {
4825 allowAdminMenuItems = true;
4826 }
4827 else if(role == nrClient) {
4828 ClientInterface *clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
4829
4830 if(clientInterface != NULL &&
4831 gameSettings.getMasterserver_admin() == clientInterface->getSessionKey()) {
4832 allowAdminMenuItems = true;
4833 }
4834 }
4835
4836 if(allowAdminMenuItems) {
4837 if(getPaused() == false) {
4838 commander.tryPauseGame(false,false);
4839 }
4840 else {
4841 commander.tryResumeGame(false,false);
4842 }
4843 }
4844 }
4845 else if(isKeyPressed(configKeys.getSDLKey("ExtraTeamColorMarker"),key, false) == true) {
4846 //printf("Toggle ExtraTeamColorMarker\n");
4847 toggleTeamColorMarker();
4848 }
4849 //switch display color
4850 //else if(key == configKeys.getCharKey("ChangeFontColor")) {
4851 else if(isKeyPressed(configKeys.getSDLKey("ChangeFontColor"),key, false) == true) {
4852 gui.switchToNextDisplayColor();
4853 }
4854 //increment speed
4855 //else if(key == configKeys.getCharKey("GameSpeedIncrease")) {
4856 else if(isKeyPressed(configKeys.getSDLKey("GameSpeedIncrease"),key, false) == true) {
4857 bool speedChangesAllowed= !NetworkManager::getInstance().isNetworkGameWithConnectedClients();
4858 if(speedChangesAllowed){
4859 incSpeed();
4860 }
4861 }
4862 //decrement speed
4863 //else if(key == configKeys.getCharKey("GameSpeedDecrease")) {
4864 else if(isKeyPressed(configKeys.getSDLKey("GameSpeedDecrease"),key, false) == true) {
4865 bool speedChangesAllowed= !NetworkManager::getInstance().isNetworkGameWithConnectedClients();
4866 if(speedChangesAllowed){
4867 decSpeed();
4868 }
4869 }
4870 else if(isKeyPressed(configKeys.getSDLKey("BookmarkAdd"),key, false) == true) {
4871 startMarkCell();
4872 }
4873 else if(isKeyPressed(configKeys.getSDLKey("BookmarkRemove"),key, false) == true) {
4874 isUnMarkCellEnabled = true;
4875 }
4876 else if(isKeyPressed(configKeys.getSDLKey("CameraFollowSelectedUnit"),key, false) == true) {
4877 startCameraFollowUnit();
4878 }
4879 //exit
4880 else if(isKeyPressed(configKeys.getSDLKey("ExitKey"),key, false) == true) {
4881 popupMenu.setEnabled(!popupMenu.getEnabled());
4882 popupMenu.setVisible(popupMenu.getEnabled());
4883 }
4884
4885 //hotkeys
4886 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] gameCamera.getState() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,gameCamera.getState());
4887
4888 if(gameCamera.getState() != GameCamera::sFree){
4889 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,key);
4890
4891 gui.hotKey(key);
4892 }
4893 else {
4894 //rotate camera leftt
4895 //if(key == configKeys.getCharKey("CameraRotateLeft")) {
4896 if(isKeyPressed(configKeys.getSDLKey("CameraRotateLeft"),key) == true) {
4897 gameCamera.setRotate(-1);
4898 }
4899 //rotate camera right
4900 //else if(key == configKeys.getCharKey("CameraRotateRight")){
4901 else if(isKeyPressed(configKeys.getSDLKey("CameraRotateRight"),key) == true) {
4902 gameCamera.setRotate(1);
4903 }
4904 //camera up
4905 //else if(key == configKeys.getCharKey("CameraRotateUp")) {
4906 else if(isKeyPressed(configKeys.getSDLKey("CameraRotateUp"),key) == true) {
4907 gameCamera.setMoveY(1);
4908 }
4909 //camera down
4910 //else if(key == configKeys.getCharKey("CameraRotateDown")) {
4911 else if(isKeyPressed(configKeys.getSDLKey("CameraRotateDown"),key) == true) {
4912 gameCamera.setMoveY(-1);
4913 }
4914 }
4915
4916 if(isKeyPressed(configKeys.getSDLKey("SaveGame"),key) == true) {
4917 saveGame();
4918 }
4919 }
4920 }
4921 catch(const exception &ex) {
4922 char szBuf[8096]="";
4923 snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
4924
4925 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
4926 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
4927
4928 NetworkManager &networkManager= NetworkManager::getInstance();
4929 if(networkManager.getGameNetworkInterface() != NULL) {
4930 GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
4931 networkInterface->sendTextMessage(szBuf,-1,true,"");
4932 sleep(10);
4933 networkManager.getGameNetworkInterface()->quitGame(true);
4934 }
4935 ErrorDisplayMessage(ex.what(),true);
4936 }
4937 }
4938
4939 void Game::keyUp(SDL_KeyboardEvent key) {
4940 if(this->masterserverMode == true) {
4941 return;
4942 }
4943
4944 try {
4945 if(gameStarted == false || totalRenderFps <= 0) {
4946 return;
4947 }
4948 if(currentUIState != NULL) {
4949 currentUIState->keyUp(key);
4950 return;
4951 }
4952
4953 if(chatManager.getEditEnabled()) {
4954 //send key to the chat manager
4955 chatManager.keyUp(key);
4956 }
4957 else {
4958 Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
4959
4960 //if(key == configKeys.getCharKey("ShowFullConsole")) {
4961 if(isKeyPressed(configKeys.getSDLKey("ShowFullConsole"),key) == true) {
4962 showFullConsole= false;
4963 }
4964 else if(isKeyPressed(configKeys.getSDLKey("SetMarker"),key) == true) {
4965 setMarker= false;
4966 }
4967 //else if(key == configKeys.getCharKey("CameraRotateLeft") ||
4968 // key == configKeys.getCharKey("CameraRotateRight")) {
4969 else if(isKeyPressed(configKeys.getSDLKey("CameraRotateLeft"),key) == true ||
4970 isKeyPressed(configKeys.getSDLKey("CameraRotateRight"),key) == true) {
4971 gameCamera.setRotate(0);
4972 }
4973 //else if(key == configKeys.getCharKey("CameraRotateDown") ||
4974 // key == configKeys.getCharKey("CameraRotateUp")) {
4975 else if(isKeyPressed(configKeys.getSDLKey("CameraRotateDown"),key) == true ||
4976 isKeyPressed(configKeys.getSDLKey("CameraRotateUp"),key) == true) {
4977
4978 gameCamera.setMoveY(0);
4979 }
4980 //else if(key == configKeys.getCharKey("CameraModeUp")){
4981 else if(isKeyPressed(configKeys.getSDLKey("CameraModeUp"),key) == true) {
4982 gameCamera.setMoveZ(0);
4983 camUpButtonDown= false;
4984 calcCameraMoveZ();
4985 }
4986 //else if(key == configKeys.getCharKey("CameraModeDown")){
4987 else if(isKeyPressed(configKeys.getSDLKey("CameraModeDown"),key) == true) {
4988 gameCamera.setMoveZ(0);
4989 camDownButtonDown= false;
4990 calcCameraMoveZ();
4991 }
4992 //else if(key == configKeys.getCharKey("CameraModeLeft")){
4993 else if(isKeyPressed(configKeys.getSDLKey("CameraModeLeft"),key) == true) {
4994 gameCamera.setMoveX(0);
4995 camLeftButtonDown= false;
4996 calcCameraMoveX();
4997 }
4998 //else if(key == configKeys.getCharKey("CameraModeRight")){
4999 else if(isKeyPressed(configKeys.getSDLKey("CameraModeRight"),key) == true) {
5000 gameCamera.setMoveX(0);
5001 camRightButtonDown= false;
5002 calcCameraMoveX();
5003 }
5004 }
5005 }
5006 catch(const exception &ex) {
5007 char szBuf[8096]="";
5008 snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
5009
5010 SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
5011 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
5012
5013 NetworkManager &networkManager= NetworkManager::getInstance();
5014 if(networkManager.getGameNetworkInterface() != NULL) {
5015 GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
5016 networkInterface->sendTextMessage(szBuf,-1,true,"");
5017 sleep(10);
5018 networkManager.getGameNetworkInterface()->quitGame(true);
5019 }
5020 ErrorDisplayMessage(ex.what(),true);
5021 }
5022 }
5023
5024 void Game::calcCameraMoveX(){
5025 //move camera left
5026 if(camLeftButtonDown == true){
5027 gameCamera.setMoveX(-1);
5028 }
5029 //move camera right
5030 else if(camRightButtonDown == true){
5031 gameCamera.setMoveX(1);
5032 }
5033 }
5034 void Game::calcCameraMoveZ(){
5035 //move camera up
5036 if(camUpButtonDown == true){
5037 gameCamera.setMoveZ(1);
5038 }
5039 //move camera down
5040 else if(camDownButtonDown == true){
5041 gameCamera.setMoveZ(-1);
5042 }
5043
5044 }
5045
5046 void Game::keyPress(SDL_KeyboardEvent c) {
5047 if(this->masterserverMode == true) {
5048 return;
5049 }
5050
5051 if(gameStarted == false || totalRenderFps <= 0) {
5052 return;
5053 }
5054 if(currentUIState != NULL) {
5055 currentUIState->keyPress(c);
5056 return;
5057 }
5058
5059 chatManager.keyPress(c);
5060 }
5061
5062 Stats Game::getEndGameStats() {
5063 Stats endStats;
5064 endStats = *(world.getStats());
5065 //NetworkManager &networkManager= NetworkManager::getInstance();
5066 if (this->masterserverMode == true) {
5067 endStats.setIsMasterserverMode(true);
5068 }
5069 return endStats;
5070 }
5071
5072 Stats Game::quitGame() {
5073 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
5074
5075 if(quitGameCalled == true) {
5076 Stats endStats = getEndGameStats();
5077 return endStats;
5078 }
5079 quitGameCalled = true;
5080
5081 NetworkManager &networkManager= NetworkManager::getInstance();
5082 NetworkRole role = networkManager.getNetworkRole();
5083 string suffix = "_client";
5084 if(role == nrServer) {
5085 suffix = "_server";
5086 }
5087 this->DumpCRCWorldLogIfRequired(suffix);
5088
5089 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled == true) {
5090 world.DumpWorldToLog();
5091 }
5092 //printf("Check savegame\n");
5093 //printf("Saving...\n");
5094 if(Config::getInstance().getBool("AutoTest")){
5095 this->saveGame(GameConstants::saveGameFileAutoTestDefault);
5096 }
5097
5098 Stats endStats = getEndGameStats();
5099
5100 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
5101
5102 //printf("In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
5103 NetworkManager::getInstance().end();
5104 //sleep(0);
5105
5106 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
5107
5108 return endStats;
5109 }
5110
5111 void Game::DumpCRCWorldLogIfRequired(string fileSuffix) {
5112 bool isNetworkGame = this->gameSettings.isNetworkGame();
5113 if(isNetworkGame == true) {
5114 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Check save world CRC to log. isNetworkGame = %d fileSuffix = %s\n",isNetworkGame,fileSuffix.c_str());
5115
5116 GameSettings *settings = world.getGameSettingsPtr();
5117 if(settings != NULL &&
5118 (isFlagType1BitEnabled(ft1_network_synch_checks_verbose) == true ||
5119 isFlagType1BitEnabled(ft1_network_synch_checks) == true)) {
5120 string debugCRCWorldLogFile = Config::getInstance().getString("DebugCRCWorldLogFile","debugCRCWorld.log");
5121 debugCRCWorldLogFile += fileSuffix;
5122
5123 if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
5124 debugCRCWorldLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugCRCWorldLogFile;
5125 }
5126 else {
5127 string userData = Config::getInstance().getString("UserData_Root","");
5128 if(userData != "") {
5129 endPathWithSlash(userData);
5130 }
5131 debugCRCWorldLogFile = userData + debugCRCWorldLogFile;
5132 }
5133
5134 printf("Save to log debugCRCWorldLogFile = %s\n",debugCRCWorldLogFile.c_str());
5135
5136 #if defined(WIN32) && !defined(__MINGW32__)
5137 FILE *fp = _wfopen(utf8_decode(debugCRCWorldLogFile).c_str(), L"w");
5138 std::ofstream logFile(fp);
5139 #else
5140 std::ofstream logFile;
5141 logFile.open(debugCRCWorldLogFile.c_str(), ios_base::out | ios_base::trunc);
5142 #endif
5143 logFile << "World CRC debug information:" << std::endl;
5144 logFile << "============================" << std::endl;
5145 logFile << "Software version: " << glestVersionString << "-" << getCompilerNameString() << "-" << getGITRevisionString() << std::endl;
5146 logFile << "Maximum framecount: " << world.getFaction(0)->getCRC_DetailsForWorldFrameCount() << std::endl;
5147
5148
5149 for(unsigned int worldFrameIndex = 0; worldFrameIndex < world.getFaction(0)->getCRC_DetailsForWorldFrameCount(); ++worldFrameIndex) {
5150 //factions (and their related info)
5151 for(int i = 0; i < world.getFactionCount(); ++i) {
5152 logFile << "Faction detail for index: " << i << std::endl;
5153 logFile << "--------------------------" << std::endl;
5154
5155 std::pair<int,string> details = world.getFaction(i)->getCRC_DetailsForWorldFrameIndex(worldFrameIndex);
5156
5157 logFile << string("** world frame: ") << details.first << std::endl;
5158 logFile << details.second << std::endl;
5159 }
5160 }
5161
5162 logFile.close();
5163 #if defined(WIN32) && !defined(__MINGW32__)
5164 if(fp) {
5165 fclose(fp);
5166 }
5167 #endif
5168
5169 }
5170 }
5171 }
5172
5173 void Game::exitGameState(Program *program, Stats &endStats) {
5174 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
5175
5176 Game *game = dynamic_cast<Game *>(program->getState());
5177
5178 //printf("game = %p\n",game);
5179
5180 if(game) {
5181 game->setEndGameTeamWinnersAndLosers();
5182 game->endGame();
5183 }
5184
5185 if((game != NULL && game->isMasterserverMode() == true) ||
5186 Config::getInstance().getBool("AutoTest") == true) {
5187 printf("Game ending with stats:\n");
5188 printf("-----------------------\n");
5189
5190 string gameStats = endStats.getStats();
5191 printf("%s",gameStats.c_str());
5192
5193 printf("-----------------------\n");
5194 }
5195
5196 ProgramState *newState = new BattleEnd(program, &endStats, game);
5197
5198 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
5199
5200 program->setState(newState, false);
5201
5202 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
5203 }
5204
5205 // ==================== PRIVATE ====================
5206
5207 void Game::highlightUnit(int unitId,float radius, float thickness, Vec4f color) {
5208 HighlightSpecialUnitInfo info;
5209 info.radius = radius;
5210 info.thickness = thickness;
5211 info.color = color;
5212 unitHighlightList[unitId] = info;
5213 }
5214
5215 void Game::unhighlightUnit(int unitId) {
5216 if(unitHighlightList.find(unitId) != unitHighlightList.end()) {
5217 unitHighlightList.erase(unitId);
5218 }
5219 }
5220
5221 // ==================== render ====================
5222
5223 void Game::render3d(){
5224 Chrono chrono;
5225 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
5226
5227 Renderer &renderer= Renderer::getInstance();
5228
5229 //init
5230 renderer.reset3d();
5231 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [reset3d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5232 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5233
5234 // renderer.computeVisibleQuad();
5235 // if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [computeVisibleQuad]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5236 // if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5237
5238 renderer.loadGameCameraMatrix();
5239 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [loadGameCameraMatrix]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5240 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5241
5242 renderer.computeVisibleQuad();
5243 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [computeVisibleQuad]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5244 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5245
5246 renderer.setupLighting();
5247 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [setupLighting]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5248 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5249
5250 //shadow map
5251 renderer.renderShadowsToTexture(avgRenderFps);
5252 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderShadowsToTexture]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5253 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5254
5255 //clear buffers
5256 renderer.clearBuffers();
5257 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d renderFps = %d took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5258 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5259
5260 //surface
5261 renderer.renderSurface(avgRenderFps);
5262 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderSurface]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5263 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5264
5265 //selection circles
5266 renderer.renderSelectionEffects(healthbarMode);
5267 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderSelectionEffects]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5268 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5269
5270 // renderTeamColorCircle
5271 if((renderExtraTeamColor&renderTeamColorCircleBit)>0){
5272 renderer.renderTeamColorCircle();
5273 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderObjects]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5274 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5275 }
5276
5277 renderer.renderSpecialHighlightUnits(unitHighlightList);
5278
5279 // renderTeamColorCircle
5280 renderer.renderMorphEffects();
5281 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderObjects]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5282 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5283
5284 //objects
5285 renderer.renderObjects(avgRenderFps);
5286 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderObjects]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5287 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5288
5289 //ground units
5290 renderer.renderUnits(false, avgRenderFps);
5291 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderUnits]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5292 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5293
5294 //water
5295 renderer.renderWater();
5296 renderer.renderWaterEffects();
5297 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderWater]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5298 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5299
5300 //air units
5301 renderer.renderUnits(true, avgRenderFps);
5302 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderUnits]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5303 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5304
5305 //particles
5306 renderer.renderParticleManager(rsGame);
5307 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderParticleManager]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5308 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5309
5310 //renderOnTopBars (aka Healthbars)
5311 if(photoModeEnabled == false) {
5312 renderer.renderHealthBars(healthbarMode);
5313 }
5314
5315 // renderTeamColorPlane
5316 if((renderExtraTeamColor&renderTeamColorPlaneBit)>0){
5317 renderer.renderTeamColorPlane();
5318 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderObjects]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5319 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5320 }
5321
5322 //mouse 3d
5323 renderer.renderMouse3d();
5324 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderMouse3d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5325
5326 renderer.renderUnitsToBuild(avgRenderFps);
5327 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderUnitsToBuild]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
5328 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
5329
5330 renderer.setLastRenderFps(lastRenderFps);
5331 }
5332
5333 void Game::updateWorldStats() {
5334 world.getStats()->setWorldTimeElapsed(world.getTimeFlow()->getTime());
5335
5336 if(difftime((long int)time(NULL),lastMaxUnitCalcTime) >= 1) {
5337 lastMaxUnitCalcTime = time(NULL);
5338
5339 int totalUnitcount = 0;
5340 for(int i = 0; i < world.getFactionCount(); ++i) {
5341 Faction *faction= world.getFaction(i);
5342 totalUnitcount += faction->getUnitCount();
5343 }
5344
5345 if(world.getStats()->getMaxConcurrentUnitCount() < totalUnitcount) {
5346 world.getStats()->setMaxConcurrentUnitCount(totalUnitcount);
5347 }
5348 world.getStats()->setTotalEndGameConcurrentUnitCount(totalUnitcount);
5349 world.getStats()->setFramesPlayed(world.getFrameCount());
5350 }
5351 }
5352
5353 string Game::getDebugStats(std::map<int,string> &factionDebugInfo) {
5354 string str = "";
5355
5356 if(this->masterserverMode == false) {
5357 str+= "MouseXY: " + intToStr(mouseX) + "," + intToStr(mouseY)+"\n";
5358
5359 if(world.getMap()->isInsideSurface(world.getMap()->toSurfCoords(mouseCellPos)) == true) {
5360 str+= "MouseXY cell coords: " + intToStr(mouseCellPos.x) + "," + intToStr(mouseCellPos.y)+"\n";
5361 }
5362
5363 str+= "PosObjWord: " + intToStr(gui.getPosObjWorld().x) + "," + intToStr(gui.getPosObjWorld().y)+"\n";
5364 }
5365
5366 str+= "Render FPS: " + intToStr(lastRenderFps) + "[" + intToStr(avgRenderFps) + "]\n";
5367 str+= "Update FPS: " + intToStr(lastUpdateFps) + "[" + intToStr(avgUpdateFps) + "]\n";
5368
5369 if(this->masterserverMode == false) {
5370 str+= "GameCamera pos: " + floatToStr(gameCamera.getPos().x)+","+floatToStr(gameCamera.getPos().y)+","+floatToStr(gameCamera.getPos().z)+"\n";
5371 //str+= "Cached surfacedata: " + intToStr(renderer.getCachedSurfaceDataSize())+"\n";
5372 }
5373
5374 //intToStr(stats.getFramesToCalculatePlaytime()/GameConstants::updateFps/60
5375 str+= "Time: " + floatToStr(world.getTimeFlow()->getTime(),2) + " [" + floatToStr((double)world.getStats()->getFramesToCalculatePlaytime() / (float)GameConstants::updateFps / 60.0,2) + "]\n";
5376
5377 if(SystemFlags::getThreadedLoggerRunning() == true) {
5378 str+= "Log buffer count: " + intToStr(SystemFlags::getLogEntryBufferCount())+"\n";
5379 }
5380
5381 str+= "UnitRangeCellsLookupItemCache: " + world.getUnitUpdater()->getUnitRangeCellsLookupItemCacheStats()+"\n";
5382 str+= "ExploredCellsLookupItemCache: " + world.getExploredCellsLookupItemCacheStats()+"\n";
5383 str+= "FowAlphaCellsLookupItemCache: " + world.getFowAlphaCellsLookupItemCacheStats()+"\n";
5384
5385 const string selectionType = toLower(Config::getInstance().getString("SelectionType",Config::colorPicking));
5386 str += "Selection type: " + toLower(selectionType) + "\n";
5387
5388 if(selectionType == Config::colorPicking) {
5389 str += "Color picking used color list size: " + intToStr(BaseColorPickEntity::getUsedColorIDListSize()) +"\n";
5390 }
5391
5392 //str+= "AllFactionsCacheStats: " + world.getAllFactionsCacheStats()+"\n";
5393 //str+= "AttackWarningCount: " + intToStr(world.getUnitUpdater()->getAttackWarningCount()) + "\n";
5394
5395 str+= "Map: " + gameSettings.getMap() +"\n";
5396 str+= "Tileset: " + gameSettings.getTileset() +"\n";
5397 str+= "Techtree: " + gameSettings.getTech() +"\n";
5398
5399 if(this->masterserverMode == false) {
5400 Renderer &renderer= Renderer::getInstance();
5401 str+= "Triangle count: " + intToStr(renderer.getTriangleCount())+"\n";
5402 str+= "Vertex count: " + intToStr(renderer.getPointCount())+"\n";
5403 }
5404
5405 str+= "Frame count:" + intToStr(world.getFrameCount())+"\n";
5406
5407 //visible quad
5408 if(this->masterserverMode == false) {
5409 Renderer &renderer= Renderer::getInstance();
5410 Quad2i visibleQuad= renderer.getVisibleQuad();
5411 //Quad2i visibleQuadCamera= renderer.getVisibleQuadFromCamera();
5412
5413 str+= "Visible quad: ";
5414 for(int i= 0; i<4; ++i){
5415 str+= "(" + intToStr(visibleQuad.p[i].x) + "," +intToStr(visibleQuad.p[i].y) + ") ";
5416 }
5417 // str+= "\n";
5418 // str+= "Visible quad camera: ";
5419 // for(int i= 0; i<4; ++i){
5420 // str+= "(" + intToStr(visibleQuadCamera.p[i].x) + "," +intToStr(visibleQuadCamera.p[i].y) + ") ";
5421 // }
5422 str+= "\n";
5423
5424 str+= "Visible quad area: " + floatToStr(visibleQuad.area()) +"\n";
5425 // str+= "Visible quad camera area: " + floatToStr(visibleQuadCamera.area()) +"\n";
5426
5427 // Rect2i boundingRect= visibleQuad.computeBoundingRect();
5428 // Rect2i scaledRect= boundingRect/Map::cellScale;
5429 // scaledRect.clamp(0, 0, world.getMap()->getSurfaceW()-1, world.getMap()->getSurfaceH()-1);
5430 // renderer.renderText3D("#1", coreData.getMenuFontNormal3D(), Vec3f(1.0f), scaledRect.p[0].x, scaledRect.p[0].y, false);
5431 // renderer.renderText3D("#2", coreData.getMenuFontNormal3D(), Vec3f(1.0f), scaledRect.p[1].x, scaledRect.p[1].y, false);
5432 }
5433
5434 int totalUnitcount = 0;
5435 for(int i = 0; i < world.getFactionCount(); ++i) {
5436 Faction *faction= world.getFaction(i);
5437 totalUnitcount += faction->getUnitCount();
5438 }
5439
5440 if(this->masterserverMode == false) {
5441 Renderer &renderer= Renderer::getInstance();
5442 VisibleQuadContainerCache &qCache =renderer.getQuadCache();
5443 int visibleUnitCount = (int)qCache.visibleQuadUnitList.size();
5444 str+= "Visible unit count: " + intToStr(visibleUnitCount) + " total: " + intToStr(totalUnitcount) + "\n";
5445
5446 int visibleObjectCount = (int)qCache.visibleObjectList.size();
5447 str+= "Visible object count: " + intToStr(visibleObjectCount) +"\n";
5448 }
5449 else {
5450 str+= "Total unit count: " + intToStr(totalUnitcount) + "\n";
5451 }
5452
5453 // resources
5454 for(int i = 0; i < world.getFactionCount(); ++i) {
5455 string factionInfo = this->gameSettings.getNetworkPlayerName(i);
5456 //factionInfo += " [" + this->gameSettings.getNetworkPlayerUUID(i) + "]";
5457 float multi=world.getStats()->getResourceMultiplier(i);
5458 string multiplier="["+floatToStr(multi,1)+"]";
5459 switch(this->gameSettings.getFactionControl(i)) {
5460 case ctCpuEasy:
5461 factionInfo += " CPU Easy"+multiplier;
5462 break;
5463 case ctCpu:
5464 factionInfo += " CPU Normal"+multiplier;
5465 break;
5466 case ctCpuUltra:
5467 factionInfo += " CPU Ultra"+multiplier;
5468 break;
5469 case ctCpuMega:
5470 factionInfo += " CPU Mega"+multiplier;
5471 break;
5472 }
5473
5474 factionInfo += " [" + formatString(this->gameSettings.getFactionTypeName(i)) +
5475 " team: " + intToStr(this->gameSettings.getTeam(i)) + "]";
5476
5477 // bool showResourceDebugInfo = true;
5478 // if(showResourceDebugInfo == true) {
5479 // factionInfo +=" res: ";
5480 // for(int j = 0; j < world.getTechTree()->getResourceTypeCount(); ++j) {
5481 // factionInfo += world.getFaction(i)->getResource(j)->getType()->getName()+":"+intToStr(world.getFaction(i)->getResource(j)->getAmount());
5482 // factionInfo += " ";
5483 // }
5484 // }
5485
5486 factionDebugInfo[i] = factionInfo;
5487 }
5488
5489 return str;
5490 }
5491
5492 void Game::render2d() {
5493 Renderer &renderer= Renderer::getInstance();
5494 //Config &config= Config::getInstance();
5495 CoreData &coreData= CoreData::getInstance();
5496
5497 //init
5498 renderer.reset2d();
5499
5500 //HUD
5501 if(visibleHUD == true && photoModeEnabled == false) {
5502 renderer.renderHud();
5503 }
5504 //display
5505 renderer.renderDisplay();
5506
5507 //minimap
5508 if(photoModeEnabled == false) {
5509 renderer.renderMinimap();
5510 }
5511
5512 renderer.renderVisibleMarkedCells();
5513 renderer.renderVisibleMarkedCells(true,lastMousePos.x,lastMousePos.y);
5514
5515 //selection
5516 renderer.renderSelectionQuad();
5517
5518 //highlighted Cells
5519 renderer.renderHighlightedCellsOnMinimap();
5520
5521 if(switchTeamConfirmMessageBox.getEnabled() == true) {
5522 renderer.renderMessageBox(&switchTeamConfirmMessageBox);
5523 }
5524
5525 if(disconnectPlayerConfirmMessageBox.getEnabled() == true) {
5526 renderer.renderMessageBox(&disconnectPlayerConfirmMessageBox);
5527 }
5528
5529 //exit message box
5530 if(errorMessageBox.getEnabled()) {
5531 renderer.renderMessageBox(&errorMessageBox);
5532 }
5533 if(mainMessageBox.getEnabled()) {
5534 renderer.renderMessageBox(&mainMessageBox);
5535 }
5536
5537 //script message box
5538 if( mainMessageBox.getEnabled() == false &&
5539 errorMessageBox.getEnabled() == false &&
5540 scriptManager.getMessageBoxEnabled()) {
5541 renderer.renderMessageBox(scriptManager.getMessageBox());
5542 }
5543
5544 //script display text
5545 if(!scriptManager.getDisplayText().empty() && !scriptManager.getMessageBoxEnabled()){
5546 Vec4f fontColor = getGui()->getDisplay()->getColor();
5547
5548 if(Renderer::renderText3DEnabled == true) {
5549 renderer.renderText3D(
5550 scriptManager.getDisplayText(), coreData.getMenuFontNormal3D(),
5551 Vec3f(fontColor.x,fontColor.y,fontColor.z), 200, 660, false);
5552 }
5553 else {
5554 renderer.renderText(
5555 scriptManager.getDisplayText(), coreData.getMenuFontNormal(),
5556 Vec3f(fontColor.x,fontColor.y,fontColor.z), 200, 660, false);
5557 }
5558 }
5559
5560 renderVideoPlayer();
5561
5562 renderer.renderPopupMenu(&popupMenu);
5563 renderer.renderPopupMenu(&popupMenuSwitchTeams);
5564 renderer.renderPopupMenu(&popupMenuDisconnectPlayer);
5565
5566 if(program != NULL) program->renderProgramMsgBox();
5567
5568 renderer.renderChatManager(&chatManager);
5569
5570 //debug info
5571 bool perfLogging = false;
5572 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true ||
5573 SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
5574 perfLogging = true;
5575 }
5576
5577 string str="";
5578 std::map<int,string> factionDebugInfo;
5579
5580 if( renderer.getShowDebugUI() == true ||
5581 (perfLogging == true && difftime((long int)time(NULL),lastRenderLog2d) >= 1)) {
5582 str = getDebugStats(factionDebugInfo);
5583 }
5584
5585 if(this->getRenderInGamePerformance() == true) {
5586 renderer.renderPerformanceStats();
5587 }
5588 else {
5589 static time_t lastGamePerfCheck = time(NULL);
5590 if(difftime((long int)time(NULL),lastGamePerfCheck) > 3) {
5591 lastGamePerfCheck = time(NULL);
5592
5593 getGamePerformanceCounts(true);
5594 }
5595 }
5596
5597 if(renderer.getShowDebugUI() == true) {
5598 const Metrics &metrics= Metrics::getInstance();
5599 int mh= metrics.getMinimapH();
5600
5601 if(this->getRenderInGamePerformance() == true) {
5602 mh = mh + ((int)gamePerformanceCounts.size() * 14);
5603 }
5604
5605 const Vec4f fontColor=getGui()->getDisplay()->getColor();
5606
5607 if(Renderer::renderText3DEnabled == true) {
5608 renderer.renderTextShadow3D(str, coreData.getMenuFontNormal3D(),
5609 fontColor, 10, metrics.getVirtualH() - mh - 60, false);
5610 }
5611 else {
5612 renderer.renderTextShadow(str, coreData.getMenuFontNormal(),
5613 fontColor, 10, metrics.getVirtualH() - mh - 60, false);
5614 }
5615
5616 vector<string> lineTokens;
5617 Tokenize(str,lineTokens,"\n");
5618 int fontHeightNormal = (Renderer::renderText3DEnabled == true ? coreData.getMenuFontNormal3D()->getMetrics()->getHeight("W") : coreData.getMenuFontNormal()->getMetrics()->getHeight("W"));
5619 int fontHeightBig = (Renderer::renderText3DEnabled == true ? coreData.getMenuFontBig3D()->getMetrics()->getHeight("W") : coreData.getMenuFontBig()->getMetrics()->getHeight("W"));
5620 int playerPosY = (int)lineTokens.size() * fontHeightNormal;
5621
5622 //printf("lineTokens.size() = %d\n",lineTokens.size());
5623
5624 for(int i = 0; i < world.getFactionCount(); ++i) {
5625 string factionInfo = factionDebugInfo[i];
5626 Vec3f playerColor = world.getFaction(i)->getTexture()->getPixmapConst()->getPixel3f(0, 0);
5627
5628 if(Renderer::renderText3DEnabled == true) {
5629 renderer.renderText3D(factionInfo, coreData.getMenuFontBig3D(),
5630 Vec4f(playerColor.x,playerColor.y,playerColor.z,1.0),
5631 10,
5632 //metrics.getVirtualH() - mh - 90 - 280 - (i * 16),
5633 metrics.getVirtualH() - mh - 60 - playerPosY - fontHeightBig - (fontHeightBig * i),
5634 false);
5635 }
5636 else {
5637 renderer.renderText(factionInfo, coreData.getMenuFontBig(),
5638 Vec4f(playerColor.x,playerColor.y,playerColor.z,1.0),
5639 10,
5640 //metrics.getVirtualH() - mh - 90 - 280 - (i * 16),
5641 metrics.getVirtualH() - mh - 60 - playerPosY - fontHeightBig - (fontHeightBig * i),
5642 false);
5643 }
5644 }
5645
5646 if((renderer.getShowDebugUILevel() & debugui_unit_titles) == debugui_unit_titles) {
5647 if(renderer.getAllowRenderUnitTitles() == false) {
5648 renderer.setAllowRenderUnitTitles(true);
5649 }
5650
5651 if(Renderer::renderText3DEnabled == true) {
5652 renderer.renderUnitTitles3D(coreData.getMenuFontNormal3D(),Vec3f(1.0f));
5653 }
5654 else {
5655 renderer.renderUnitTitles(coreData.getMenuFontNormal(),Vec3f(1.0f));
5656 }
5657 }
5658 }
5659
5660 //network status
5661 if(renderNetworkStatus == true) {
5662 if(NetworkManager::getInstance().getGameNetworkInterface() != NULL) {
5663 const Metrics &metrics= Metrics::getInstance();
5664 int mx= metrics.getMinimapX();
5665 //int my= metrics.getMinimapY();
5666 int mw= metrics.getMinimapW();
5667 //int mh= metrics.getMinimapH();
5668 const Vec4f fontColor=getGui()->getDisplay()->getColor();
5669
5670 if(Renderer::renderText3DEnabled == true) {
5671 renderer.renderTextShadow3D(
5672 NetworkManager::getInstance().getGameNetworkInterface()->getNetworkStatus(),
5673 coreData.getMenuFontNormal3D(),
5674 fontColor, mx + mw + 5 , metrics.getVirtualH()-30-20, false);
5675 }
5676 else {
5677 renderer.renderTextShadow(
5678 NetworkManager::getInstance().getGameNetworkInterface()->getNetworkStatus(),
5679 coreData.getMenuFontNormal(),
5680 fontColor, mx + mw + 5 , metrics.getVirtualH()-30-20, false);
5681 }
5682 }
5683 }
5684
5685 // clock
5686 if(photoModeEnabled == false && timeDisplay == true) {
5687 renderer.renderClock();
5688 }
5689
5690 //resource info
5691 if(photoModeEnabled == false) {
5692 if(this->masterserverMode == false) {
5693 renderer.renderResourceStatus();
5694 }
5695 renderer.renderConsole(&console,showFullConsole?consoleFull:consoleNormal);
5696 }
5697
5698 //2d mouse
5699 renderer.renderMouse2d(mouseX, mouseY, mouse2d, gui.isSelectingPos()? 1.f: 0.f);
5700
5701 if(perfLogging == true && difftime((long int)time(NULL),lastRenderLog2d) >= 1) {
5702 lastRenderLog2d = time(NULL);
5703
5704 if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] Statistics: %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,str.c_str());
5705 }
5706 }
5707
5708
5709 // ==================== misc ====================
5710
5711 void Game::checkWinner() {
5712 // lookup int is team #, value is players alive on team
5713 std::map<int, int> teamsAlive = getTeamsAlive();
5714
5715 if(gameOver == false || teamsAlive.size() > 1) {
5716 if(gameSettings.getDefaultVictoryConditions()) {
5717 checkWinnerStandard();
5718 }
5719 else {
5720 checkWinnerScripted();
5721 }
5722 }
5723 }
5724
5725 void Game::setEndGameTeamWinnersAndLosers() {
5726 //bool lose= false;
5727 bool checkTeamIndex = !(this->masterserverMode == false && world.getThisFaction()->getPersonalityType() != fpt_Observer);
5728
5729 // lookup int is team #, value is players alive on team
5730 std::map<int,int> teamsAlive;
5731 for(int i = 0; i < world.getFactionCount(); ++i) {
5732 if(checkTeamIndex == false || i != world.getThisFactionIndex()) {
5733 if(factionLostGame(world.getFaction(i)) == false) {
5734 teamsAlive[world.getFaction(i)->getTeam()] = teamsAlive[world.getFaction(i)->getTeam()] + 1;
5735 }
5736 }
5737 }
5738
5739 // did some team win
5740 if(teamsAlive.size() <= 1) {
5741 for(int i=0; i< world.getFactionCount(); ++i) {
5742 if(checkTeamIndex == false || i != world.getThisFactionIndex()) {
5743 if(teamsAlive.find(world.getFaction(i)->getTeam()) != teamsAlive.end()) {
5744 world.getStats()->setVictorious(i);
5745 }
5746 else if(i == world.getThisFactionIndex()) {
5747 //lose= true;
5748 }
5749 }
5750 }
5751 bool firstGameOverTrigger = false;
5752 if(gameOver == false) {
5753 firstGameOverTrigger = true;
5754 gameOver= true;
5755 }
5756 if( this->gameSettings.isNetworkGame() == false ||
5757 this->gameSettings.getEnableObserverModeAtEndGame() == true) {
5758 // Let the happy winner view everything left in the world
5759
5760 // This caused too much LAG for network games
5761 if(this->gameSettings.isNetworkGame() == false) {
5762 Renderer::getInstance().setPhotoMode(true);
5763 gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT);
5764 }
5765 // END
5766 }
5767
5768 if(firstGameOverTrigger == true) {
5769 scriptManager.onGameOver(true);
5770 }
5771
5772 if(world.getFactionCount() == 1 && world.getFaction(0)->getPersonalityType() == fpt_Observer) {
5773 //printf("!!!!!!!!!!!!!!!!!!!!");
5774
5775 //gameCamera.setMoveY(100.0);
5776 gameCamera.zoom(-300);
5777 //gameCamera.update();
5778 }
5779 // else {
5780 // if(lose == true) {
5781 // showLoseMessageBox();
5782 // }
5783 // else {
5784 // showWinMessageBox();
5785 // }
5786 // }
5787 }
5788 }
5789
5790 std::map<int, int> Game::getTeamsAlive() {
5791 std::map<int, int> teamsAlive;
5792 for (int factionIndex = 0; factionIndex < world.getFactionCount(); ++factionIndex) {
5793 if (factionIndex != world.getThisFactionIndex()) {
5794 if (factionLostGame(world.getFaction(factionIndex)) == false) {
5795 teamsAlive[world.getFaction(factionIndex)->getTeam()] =
5796 teamsAlive[world.getFaction(factionIndex)->getTeam()] + 1;
5797 }
5798 }
5799 }
5800 // did some team win
5801 return teamsAlive;
5802 }
5803
5804 void Game::checkWinnerStandardHeadlessOrObserver() {
5805 // lookup int is team #, value is players alive on team
5806 std::map<int, int> teamsAlive = getTeamsAlive();
5807
5808 // did some team win
5809 if (teamsAlive.size() <= 1) {
5810 if (this->masterserverMode == true) {
5811 printf("Game finished...\n");
5812 }
5813 for (int factionIndex = 0; factionIndex < world.getFactionCount(); ++factionIndex) {
5814
5815 Faction* faction = world.getFaction(factionIndex);
5816 if (factionIndex != world.getThisFactionIndex() &&
5817 teamsAlive.find(faction->getTeam()) != teamsAlive.end()) {
5818
5819 world.getStats()->setVictorious(factionIndex);
5820 if (this->masterserverMode == true) {
5821
5822 printf("Player: %s is on the winning team #: %d\n",
5823 this->gameSettings.getNetworkPlayerName(factionIndex).c_str(),
5824 faction->getTeam());
5825 }
5826 }
5827 }
5828 bool wasGameOverAlready = gameOver;
5829 gameOver = true;
5830
5831 // Only need to process this once
5832 if(wasGameOverAlready == false) {
5833 if (this->gameSettings.isNetworkGame() == false ||
5834 this->gameSettings.getEnableObserverModeAtEndGame() == true) {
5835
5836 // Let the happy winner view everything left in the world
5837 // This caused too much LAG for network games
5838 if (this->gameSettings.isNetworkGame() == false) {
5839
5840 Renderer::getInstance().setPhotoMode(true);
5841 gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT);
5842 }
5843 // END
5844 }
5845 scriptManager.onGameOver(true);
5846 if (world.getFactionCount() == 1 &&
5847 world.getFaction(0)->getPersonalityType() == fpt_Observer) {
5848 gameCamera.zoom(-300);
5849 }
5850 else {
5851 showWinMessageBox();
5852 }
5853 }
5854 }
5855 }
5856
5857 void Game::checkWinnerStandardPlayer() {
5858 //lose
5859 bool lose = false;
5860 if (factionLostGame(world.getThisFaction()) == true) {
5861
5862 bool playerLostGame = true;
5863 // Team Shared units enabled?
5864 if(isFlagType1BitEnabled(ft1_allow_shared_team_units) == true) {
5865
5866 // Check if all team members have lost?
5867 for (int factionIndex = 0; factionIndex < world.getFactionCount(); ++factionIndex) {
5868
5869 if (world.getFaction(factionIndex)->getPersonalityType() != fpt_Observer) {
5870 if (world.getFaction(factionIndex)->isAlly(world.getThisFaction()) == true &&
5871 factionLostGame(world.getFaction(factionIndex)) == false) {
5872
5873 playerLostGame = false;
5874 break;
5875 }
5876 }
5877 }
5878 }
5879
5880 if(playerLostGame == true) {
5881 lose = true;
5882 for (int factionIndex = 0; factionIndex < world.getFactionCount(); ++factionIndex) {
5883
5884 if (world.getFaction(factionIndex)->getPersonalityType() != fpt_Observer) {
5885 if (world.getFaction(factionIndex)->isAlly(world.getThisFaction()) == false &&
5886 factionLostGame(world.getFaction(factionIndex)) == false) {
5887
5888 world.getStats()->setVictorious(factionIndex);
5889 }
5890 }
5891 }
5892 bool wasGameOverAlready = gameOver;
5893 gameOver = true;
5894
5895 // Only need to process losing once
5896 if(wasGameOverAlready == false) {
5897 if (this->gameSettings.isNetworkGame() == false ||
5898 this->gameSettings.getEnableObserverModeAtEndGame()
5899 == true) {
5900 // Let the poor user watch everything unfold
5901 // This caused too much LAG for network games
5902 if (this->gameSettings.isNetworkGame() == false) {
5903 Renderer::getInstance().setPhotoMode(true);
5904 gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT);
5905 }
5906 // END
5907 // but don't let him cheat via teamchat
5908 chatManager.setDisableTeamMode(true);
5909 }
5910 scriptManager.onGameOver(!lose);
5911 showLoseMessageBox();
5912 }
5913 }
5914 }
5915
5916 //win
5917 if (lose == false) {
5918 bool win = true;
5919 for (int factionIndex = 0; factionIndex < world.getFactionCount(); ++factionIndex) {
5920
5921 if (factionIndex != world.getThisFactionIndex()) {
5922 if (world.getFaction(factionIndex)->getPersonalityType() != fpt_Observer) {
5923
5924 if (factionLostGame(world.getFaction(factionIndex)) == false &&
5925 world.getFaction(factionIndex)->isAlly(world.getThisFaction()) == false) {
5926
5927 win = false;
5928 }
5929 }
5930 }
5931 }
5932
5933 if (win) {
5934 for (int factionIndex = 0; factionIndex < world.getFactionCount(); ++factionIndex) {
5935 if (world.getFaction(factionIndex)->getPersonalityType() != fpt_Observer) {
5936 if (world.getFaction(factionIndex)->isAlly(world.getThisFaction())) {
5937
5938 world.getStats()->setVictorious(factionIndex);
5939 }
5940 }
5941 }
5942
5943 bool wasGameOverAlready = gameOver;
5944 gameOver = true;
5945
5946 // Only need to process winning once
5947 if(wasGameOverAlready == false) {
5948 if (this->gameSettings.isNetworkGame() == false ||
5949 this->gameSettings.getEnableObserverModeAtEndGame() == true) {
5950 // Let the happy winner view everything left in the world
5951
5952 // This caused too much LAG for network games
5953 if (this->gameSettings.isNetworkGame() == false) {
5954 Renderer::getInstance().setPhotoMode(true);
5955 gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT);
5956 }
5957 // END
5958 }
5959 scriptManager.onGameOver(win);
5960 showWinMessageBox();
5961 }
5962 }
5963 }
5964 }
5965
5966 void Game::checkWinnerStandard() {
5967 if(world.getFactionCount() <= 0) {
5968 return;
5969 }
5970 if(this->masterserverMode == true ||
5971 world.getThisFaction()->getPersonalityType() == fpt_Observer) {
5972 checkWinnerStandardHeadlessOrObserver();
5973 }
5974 else {
5975 checkWinnerStandardPlayer();
5976 }
5977 }
5978
5979 void Game::checkWinnerScripted() {
5980 if(scriptManager.getIsGameOver()) {
5981 bool wasGameOverAlready = gameOver;
5982 gameOver = true;
5983
5984
5985 for(int index = 0; index < world.getFactionCount(); ++index) {
5986 if(scriptManager.getPlayerModifiers(index)->getWinner()) {
5987
5988 world.getStats()->setVictorious(index);
5989 }
5990 }
5991
5992 // Only need to process winning once
5993 if(wasGameOverAlready == false) {
5994 if( this->gameSettings.isNetworkGame() == false ||
5995 this->gameSettings.getEnableObserverModeAtEndGame() == true) {
5996
5997 // Let the happy winner view everything left in the world
5998 // This caused too much LAG for network games
5999 if(this->gameSettings.isNetworkGame() == false) {
6000 Renderer::getInstance().setPhotoMode(true);
6001 gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT);
6002 }
6003 // END
6004 }
6005
6006 if(this->masterserverMode == true ||
6007 world.getThisFaction()->getPersonalityType() == fpt_Observer) {
6008 showWinMessageBox();
6009 }
6010 else {
6011 scriptManager.onGameOver(scriptManager.getPlayerModifiers(world.getThisFactionIndex())->getWinner());
6012
6013 if(scriptManager.getPlayerModifiers(world.getThisFactionIndex())->getWinner()){
6014 showWinMessageBox();
6015 }
6016 else {
6017 showLoseMessageBox();
6018 }
6019 }
6020 }
6021 }
6022 }
6023
6024 bool Game::isFlagType1BitEnabled(FlagTypes1 type) const {
6025 return ((gameSettings.getFlagTypes1() & (uint32)type) == (uint32)type);
6026 }
6027
6028 bool Game::factionLostGame(int factionIndex) {
6029 return factionLostGame(world.getFaction(factionIndex));
6030 }
6031
6032 bool Game::factionLostGame(const Faction *faction) {
6033 if(faction != NULL) {
6034 for(int factionIndex=0; factionIndex<faction->getUnitCount(); ++factionIndex) {
6035 const UnitType *ut = faction->getUnit(factionIndex)->getType();
6036 if(ut->getCountInVictoryConditions() == ucvcNotSet) {
6037 if(faction->getUnit(factionIndex)->getType()->hasSkillClass(scBeBuilt)) {
6038 return false;
6039 }
6040 }
6041 else if(ut->getCountInVictoryConditions() == ucvcTrue) {
6042 return false;
6043 }
6044 }
6045 }
6046 return true;
6047 }
6048
6049 bool Game::hasBuilding(const Faction *faction) {
6050 if(faction != NULL) {
6051 for(int i=0; i<faction->getUnitCount(); ++i) {
6052 if(faction->getUnit(i)->getType()->hasSkillClass(scBeBuilt)) {
6053 return true;
6054 }
6055 }
6056 }
6057 return false;
6058 }
6059
6060 void Game::incSpeed() {
6061 if(disableSpeedChange == true) {
6062 return;
6063 }
6064
6065 Lang &lang= Lang::getInstance();
6066
6067 if(this->speed < Config::getInstance().getInt("FastSpeedLoops")) {
6068 if(this->speed == 0) {
6069 this->speed = 1;
6070 }
6071 else {
6072 this->speed++;
6073 }
6074 console.addLine(lang.getString("GameSpeedSet")+" "+((this->speed == 0)?lang.getString("Slow") : (this->speed == 1)?lang.getString("Normal"):"x"+intToStr(this->speed)));
6075 }
6076 }
6077
6078 void Game::decSpeed() {
6079 if(disableSpeedChange == true) {
6080 return;
6081 }
6082
6083 Lang &lang= Lang::getInstance();
6084 if(this->speed > 0) {
6085 this->speed--;
6086 console.addLine(lang.getString("GameSpeedSet")+" "+((this->speed == 0)?lang.getString("Slow") : (this->speed == 1)?lang.getString("Normal"):"x"+intToStr(this->speed)));
6087 }
6088 }
6089
6090 void Game::setPaused(bool value,bool forceAllowPauseStateChange,bool clearCaches, bool joinNetworkGame) {
6091 bool speedChangesAllowed= !NetworkManager::getInstance().isNetworkGame();
6092 //printf("Toggle pause value = %d, speedChangesAllowed = %d, forceAllowPauseStateChange = %d\n",value,speedChangesAllowed,forceAllowPauseStateChange);
6093
6094 if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"game.cpp line: %d setPaused value: %d clearCaches: %d forceAllowPauseStateChange: %d speedChangesAllowed: %d pausedForJoinGame: %d joinNetworkGame: %d\n",__LINE__,value,clearCaches,forceAllowPauseStateChange,speedChangesAllowed,pausedForJoinGame,joinNetworkGame);
6095 //printf("Line: %d setPaused value: %d clearCaches: %d forceAllowPauseStateChange: %d speedChangesAllowed: %d pausedForJoinGame: %d joinNetworkGame: %d\n",__LINE__,value,clearCaches,forceAllowPauseStateChange,speedChangesAllowed,pausedForJoinGame,joinNetworkGame);
6096
6097 if(forceAllowPauseStateChange == true || speedChangesAllowed == true) {
6098 //printf("setPaused paused = %d, value = %d\n",paused,value);
6099
6100 NetworkManager &networkManager= NetworkManager::getInstance();
6101
6102 // Cannot change pause state while client is joining in progress game
6103 if(pausedForJoinGame == true && joinNetworkGame == false &&
6104 networkManager.getNetworkRole() == nrServer) {
6105
6106 ServerInterface *server = NetworkManager::getInstance().getServerInterface();
6107 Lang &lang= Lang::getInstance();
6108 const vector<string> languageList = this->gameSettings.getUniqueNetworkPlayerLanguages();
6109
6110 bool haveClientConnectedButNoReady = false;
6111 for(int i = 0; i < world.getFactionCount(); ++i) {
6112 Faction *faction = world.getFaction(i);
6113
6114 MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
6115 ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
6116 if(slot != NULL && slot->isConnected() == true && slot->isReady() == false) {
6117 for(unsigned int i = 0; i < languageList.size(); ++i) {
6118
6119 char szMsg[8096]="";
6120 if(lang.hasString("JoinPlayerToCurrentGameLaunch",languageList[i]) == true) {
6121 snprintf(szMsg,8096,lang.getString("JoinPlayerToCurrentGameLaunch",languageList[i]).c_str(), slot->getName().c_str());
6122 }
6123 else {
6124 snprintf(szMsg,8096,"Player: %s is about to join the game, please wait...",slot->getName().c_str());
6125 }
6126
6127 safeMutex.ReleaseLock();
6128
6129 bool localEcho = lang.isLanguageLocal(languageList[i]);
6130 server->sendTextMessage(szMsg,-1, localEcho,languageList[i]);
6131 sleep(1);
6132
6133 haveClientConnectedButNoReady = true;
6134 }
6135 }
6136 }
6137
6138 if(haveClientConnectedButNoReady == true) {
6139 return;
6140 }
6141 }
6142
6143 Lang &lang= Lang::getInstance();
6144 if(value == false) {
6145 console.addLine(lang.getString("GameResumed"));
6146
6147 bool wasPausedForJoinGame = pausedForJoinGame;
6148 paused= false;
6149 pausedForJoinGame = false;
6150 pausedBeforeJoinGame = false;
6151 pauseStateChanged = true;
6152
6153 if(clearCaches == true) {
6154 if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"game.cpp line: %d Clear Caches for resume in progress game\n",__LINE__);
6155 //printf("Line: %d Clear Caches for resume in progress game\n",__LINE__);
6156
6157 world.clearCaches();
6158 for(int i = 0; i < world.getFactionCount(); ++i) {
6159 Faction *faction = world.getFaction(i);
6160 faction->clearCaches();
6161 }
6162 world.refreshAllUnitExplorations();
6163 }
6164 setupPopupMenus(false);
6165
6166 if(networkManager.getNetworkRole() == nrClient &&
6167 wasPausedForJoinGame == true) {
6168 initialResumeSpeedLoops = true;
6169 }
6170
6171 commander.setPauseNetworkCommands(false);
6172 }
6173 else {
6174 console.addLine(lang.getString("GamePaused"));
6175
6176 if(joinNetworkGame == true) {
6177 pausedBeforeJoinGame = paused;
6178 }
6179 paused= true;
6180 pausedForJoinGame = joinNetworkGame;
6181 pauseStateChanged = true;
6182
6183 if(clearCaches == true) {
6184 //printf("Line: %d Clear Caches for resume in progress game\n",__LINE__);
6185 if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"game.cpp line: %d Clear Caches for resume in progress game\n",__LINE__);
6186
6187 world.clearCaches();
6188 for(int i = 0; i < world.getFactionCount(); ++i) {
6189 Faction *faction = world.getFaction(i);
6190 faction->clearCaches();
6191 }
6192 world.refreshAllUnitExplorations();
6193 }
6194 pauseRequestSent=false;
6195
6196 commander.setPauseNetworkCommands(joinNetworkGame);
6197 }
6198 //printf("setPaused new paused = %d\n",paused);
6199 }
6200 }
6201
6202 bool Game::getPaused()
6203 {
6204 bool speedChangesAllowed= !NetworkManager::getInstance().isNetworkGame();
6205 if(speedChangesAllowed){
6206 if(popupMenu.getVisible() == true || popupMenuSwitchTeams.getVisible() == true){
6207 return true;
6208 }
6209 // if(mainMessageBox.getEnabled() == true || errorMessageBox.getEnabled() == true){
6210 // return true;
6211 // }
6212 if(currentUIState != NULL) {
6213 return true;
6214 }
6215 }
6216 return paused;
6217 }
6218
6219 int Game::getUpdateLoops() {
6220 if(commander.hasReplayCommandListForFrame() == true) {
6221 return 1;
6222 }
6223
6224 if(getPaused()) {
6225 return 0;
6226 }
6227 else if(this->speed == 0) {
6228 return updateFps % 2 == 0? 1: 0;
6229 }
6230 else
6231 return this->speed;
6232 }
6233
6234 void Game::showLoseMessageBox() {
6235 Lang &lang= Lang::getInstance();
6236
6237 NetworkManager &networkManager= NetworkManager::getInstance();
6238 if(networkManager.isNetworkGame() == true && networkManager.getNetworkRole() == nrServer) {
6239 showMessageBox(lang.getString("YouLose")+" "+lang.getString("ExitBattleServerQuestion"), lang.getString("BattleOver"), false);
6240 }
6241 else {
6242 showMessageBox(lang.getString("YouLose")+" "+lang.getString("ExitBattleQuestion"), lang.getString("BattleOver"), false);
6243 }
6244 }
6245
6246 void Game::showWinMessageBox() {
6247 Lang &lang= Lang::getInstance();
6248
6249 if(this->masterserverMode == true || world.getThisFaction()->getPersonalityType() == fpt_Observer) {
6250 showMessageBox(lang.getString("GameOver")+" "+lang.getString("ExitBattleQuestion"), lang.getString("BattleOver"), false);
6251 }
6252 else {
6253 showMessageBox(lang.getString("YouWin")+" "+lang.getString("ExitBattleQuestion"), lang.getString("BattleOver"), false);
6254 }
6255 }
6256
6257 void Game::showMessageBox(const string &text, const string &header, bool toggle) {
6258 if(toggle == false) {
6259 mainMessageBox.setEnabled(false);
6260 }
6261
6262 if(mainMessageBox.getEnabled() == false) {
6263 mainMessageBox.setText(text);
6264 mainMessageBox.setHeader(header);
6265 mainMessageBox.setEnabled(true);
6266 }
6267 else {
6268 mainMessageBox.setEnabled(false);
6269 }
6270 }
6271
6272 void Game::showErrorMessageBox(const string &text, const string &header, bool toggle) {
6273 if(toggle == false) {
6274 errorMessageBox.setEnabled(false);
6275 }
6276
6277 if(errorMessageBox.getEnabled() == false) {
6278 errorMessageBox.setText(text);
6279 errorMessageBox.setHeader(header);
6280 errorMessageBox.setEnabled(true);
6281 }
6282 else {
6283 errorMessageBox.setEnabled(false);
6284 }
6285 }
6286
6287 void Game::startPerformanceTimer() {
6288 captureAvgTestStatus = true;
6289 updateFpsAvgTest = -1;
6290 renderFpsAvgTest = -1;
6291 }
6292
6293 void Game::endPerformanceTimer() {
6294 captureAvgTestStatus = false;
6295 }
6296
6297 Vec2i Game::getPerformanceTimerResults() {
6298 Vec2i results(this->updateFpsAvgTest,this->renderFpsAvgTest);
6299 return results;
6300 }
6301
6302 void Game::consoleAddLine(string line) {
6303 console.addLine(line);
6304 }
6305 void Game::toggleTeamColorMarker() {
6306 renderExtraTeamColor++;
6307 renderExtraTeamColor=renderExtraTeamColor%4;
6308 }
6309
6310 void Game::addNetworkCommandToReplayList(NetworkCommand* networkCommand, int worldFrameCount) {
6311 Config &config= Config::getInstance();
6312 if(config.getBool("SaveCommandsForReplay","false") == true) {
6313 replayCommandList.push_back(make_pair(worldFrameCount,*networkCommand));
6314 }
6315 }
6316
6317 void Game::renderVideoPlayer() {
6318 if(videoPlayer != NULL) {
6319 if(videoPlayer->isPlaying() == true) {
6320 videoPlayer->playFrame(false);
6321 }
6322 else {
6323 delete videoPlayer;
6324 videoPlayer = NULL;
6325 }
6326 }
6327 }
6328
6329 void Game::playStaticVideo(const string &playVideo) {
6330 if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false &&
6331 ::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == true) {
6332
6333 //togglePauseGame(true,true);
6334 tryPauseToggle(true);
6335 setupRenderForVideo();
6336
6337
6338 // Context *c= GraphicsInterface::getInstance().getCurrentContext();
6339 // SDL_Surface *screen = static_cast<ContextGl*>(c)->getPlatformContextGlPtr()->getScreen();
6340 //
6341 // string vlcPluginsPath = Config::getInstance().getString("VideoPlayerPluginsPath","");
6342 // //printf("screen->w = %d screen->h = %d screen->format->BitsPerPixel = %d\n",screen->w,screen->h,screen->format->BitsPerPixel);
6343 // Shared::Graphics::VideoPlayer player(playVideo.c_str(),
6344 // screen,
6345 // 0,0,
6346 // screen->w,
6347 // screen->h,
6348 // screen->format->BitsPerPixel,
6349 // vlcPluginsPath,
6350 // SystemFlags::VERBOSE_MODE_ENABLED);
6351 // player.PlayVideo();
6352 //}
6353 //tryPauseToggle(false);
6354
6355 playStreamingVideo(playVideo);
6356 playingStaticVideo = true;
6357 }
6358 }
6359 void Game::playStreamingVideo(const string &playVideo) {
6360 if(videoPlayer == NULL) {
6361 if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false &&
6362 ::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == true) {
6363 Context *c= GraphicsInterface::getInstance().getCurrentContext();
6364 PlatformContextGl *glCtx = static_cast<ContextGl*>(c)->getPlatformContextGlPtr();
6365 SDL_Window *window = glCtx->getScreenWindow();
6366 SDL_Surface *screen = glCtx->getScreenSurface();
6367
6368 string vlcPluginsPath = Config::getInstance().getString("VideoPlayerPluginsPath","");
6369
6370 videoPlayer = new ::Shared::Graphics::VideoPlayer(
6371 &Renderer::getInstance(),
6372 playVideo,
6373 "",
6374 window,
6375 0,0,
6376 screen->w,
6377 screen->h,
6378 screen->format->BitsPerPixel,
6379 false,
6380 vlcPluginsPath,
6381 SystemFlags::VERBOSE_MODE_ENABLED);
6382 }
6383 }
6384 else {
6385 if(videoPlayer->isPlaying() == false) {
6386 delete videoPlayer;
6387 videoPlayer = NULL;
6388
6389 if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false &&
6390 ::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == true) {
6391 Context *c= GraphicsInterface::getInstance().getCurrentContext();
6392 PlatformContextGl *glCtx = static_cast<ContextGl*>(c)->getPlatformContextGlPtr();
6393 SDL_Window *window = glCtx->getScreenWindow();
6394 SDL_Surface *screen = glCtx->getScreenSurface();
6395
6396 string vlcPluginsPath = Config::getInstance().getString("VideoPlayerPluginsPath","");
6397
6398 videoPlayer = new ::Shared::Graphics::VideoPlayer(
6399 &Renderer::getInstance(),
6400 playVideo,
6401 "",
6402 window,
6403 0,0,
6404 screen->w,
6405 screen->h,
6406 screen->format->BitsPerPixel,
6407 false,
6408 vlcPluginsPath,
6409 SystemFlags::VERBOSE_MODE_ENABLED);
6410 }
6411 }
6412 }
6413
6414 if(videoPlayer != NULL) {
6415 videoPlayer->initPlayer();
6416 }
6417 }
6418 void Game::stopStreamingVideo(const string &playVideo) {
6419 if(videoPlayer != NULL) {
6420 videoPlayer->StopVideo();
6421 }
6422 }
6423
6424 void Game::stopAllVideo() {
6425 if(videoPlayer != NULL) {
6426 videoPlayer->StopVideo();
6427 }
6428 }
6429
6430 bool Game::clientLagHandler(int slotIndex,bool networkPauseGameForLaggedClients) {
6431 if(networkPauseGameForLaggedClients == true) {
6432 printf("**WARNING** Detected lag from client: %d networkPauseGameForLaggedClients: %d\n",slotIndex,networkPauseGameForLaggedClients);
6433 }
6434 else {
6435 printf("==> Requested Resume Game after Pause for lagging client(s)...\n");
6436 }
6437
6438 this->networkPauseGameForLaggedClientsRequested = networkPauseGameForLaggedClients;
6439 this->networkResumeGameForLaggedClientsRequested = !networkPauseGameForLaggedClients;
6440 return true;
6441 }
6442
6443 void Game::saveGame(){
6444 string file = this->saveGame(GameConstants::saveGameFilePattern);
6445 char szBuf[8096]="";
6446 Lang &lang= Lang::getInstance();
6447 snprintf(szBuf,8096,lang.getString("GameSaved","",true).c_str(),file.c_str());
6448 console.addLine(szBuf);
6449
6450 Config &config= Config::getInstance();
6451 config.setString("LastSavedGame",file);
6452 config.save();
6453 }
6454
6455 string Game::saveGame(string name, string path) {
6456 Config &config= Config::getInstance();
6457 // auto name file if using saved file pattern string
6458 if(name == GameConstants::saveGameFilePattern) {
6459 //time_t curTime = time(NULL);
6460 //struct tm *loctime = localtime (&curTime);
6461 struct tm loctime = threadsafe_localtime(systemtime_now());
6462 char szBuf2[100]="";
6463 strftime(szBuf2,100,"%Y%m%d_%H%M%S",&loctime);
6464
6465 char szBuf[8096]="";
6466 snprintf(szBuf,8096,name.c_str(),szBuf2);
6467 name = szBuf;
6468 }
6469 else if(name == GameConstants::saveGameFileAutoTestDefault) {
6470 //time_t curTime = time(NULL);
6471 //struct tm *loctime = localtime (&curTime);
6472 struct tm loctime = threadsafe_localtime(systemtime_now());
6473 char szBuf2[100]="";
6474 strftime(szBuf2,100,"%Y%m%d_%H%M%S",&loctime);
6475
6476 char szBuf[8096]="";
6477 snprintf(szBuf,8096,name.c_str(),szBuf2);
6478 name = szBuf;
6479 }
6480
6481 // Save the file now
6482 string saveGameFile = path + name;
6483 if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
6484 saveGameFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + saveGameFile;
6485 }
6486 else {
6487 string userData = config.getString("UserData_Root","");
6488 if(userData != "") {
6489 endPathWithSlash(userData);
6490 }
6491 saveGameFile = userData + saveGameFile;
6492 }
6493 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Saving game to [%s]\n",saveGameFile.c_str());
6494
6495 // This condition will re-play all the commands from a replay file
6496 // INSTEAD of saving from a saved game.
6497 if(config.getBool("SaveCommandsForReplay","false") == true) {
6498 std::map<string,string> mapTagReplacements;
6499 XmlTree xmlTreeSaveGame(XML_RAPIDXML_ENGINE);
6500
6501 xmlTreeSaveGame.init("megaglest-saved-game");
6502 XmlNode *rootNodeReplay = xmlTreeSaveGame.getRootNode();
6503
6504 //std::map<string,string> mapTagReplacements;
6505 //time_t now = time(NULL);
6506 //struct tm *loctime = localtime (&now);
6507 struct tm loctime = threadsafe_localtime(systemtime_now());
6508 char szBuf[4096]="";
6509 strftime(szBuf,4095,"%Y-%m-%d %H:%M:%S",&loctime);
6510
6511 rootNodeReplay->addAttribute("version",glestVersionString, mapTagReplacements);
6512 rootNodeReplay->addAttribute("timestamp",szBuf, mapTagReplacements);
6513
6514 XmlNode *gameNodeReplay = rootNodeReplay->addChild("Game");
6515 gameSettings.saveGame(gameNodeReplay);
6516
6517 gameNodeReplay->addAttribute("LastWorldFrameCount",intToStr(world.getFrameCount()), mapTagReplacements);
6518
6519 for(unsigned int i = 0; i < replayCommandList.size(); ++i) {
6520 std::pair<int,NetworkCommand> &cmd = replayCommandList[i];
6521 XmlNode *networkCommandNode = cmd.second.saveGame(gameNodeReplay);
6522 networkCommandNode->addAttribute("worldFrameCount",intToStr(cmd.first), mapTagReplacements);
6523 }
6524
6525 string replayFile = saveGameFile + ".replay";
6526 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Saving game replay commands to [%s]\n",replayFile.c_str());
6527 xmlTreeSaveGame.save(replayFile);
6528 }
6529
6530 XmlTree xmlTree;
6531 xmlTree.init("megaglest-saved-game");
6532 XmlNode *rootNode = xmlTree.getRootNode();
6533
6534 std::map<string,string> mapTagReplacements;
6535 //time_t now = time(NULL);
6536 //struct tm *loctime = localtime (&now);
6537 struct tm loctime = threadsafe_localtime(systemtime_now());
6538 char szBuf[4096]="";
6539 strftime(szBuf,4095,"%Y-%m-%d %H:%M:%S",&loctime);
6540
6541 rootNode->addAttribute("version",glestVersionString, mapTagReplacements);
6542 rootNode->addAttribute("timestamp",szBuf, mapTagReplacements);
6543
6544 XmlNode *gameNode = rootNode->addChild("Game");
6545 //World world;
6546 world.saveGame(gameNode);
6547 //AiInterfaces aiInterfaces;
6548 for(unsigned int i = 0; i < aiInterfaces.size(); ++i) {
6549 AiInterface *aiIntf = aiInterfaces[i];
6550 if(aiIntf != NULL) {
6551 aiIntf->saveGame(gameNode);
6552 }
6553 }
6554 //Gui gui;
6555 gui.saveGame(gameNode);
6556 //GameCamera gameCamera;
6557 gameCamera.saveGame(gameNode);
6558 //Commander commander;
6559 //Console console;
6560 //ChatManager chatManager;
6561 //ScriptManager scriptManager;
6562 scriptManager.saveGame(gameNode);
6563
6564 //misc
6565 //Checksum checksum;
6566 gameNode->addAttribute("checksum",intToStr(checksum.getSum()), mapTagReplacements);
6567 //string loadingText;
6568 // int mouse2d;
6569 gameNode->addAttribute("mouse2d",intToStr(mouse2d), mapTagReplacements);
6570 // int mouseX;
6571 gameNode->addAttribute("mouseX",intToStr(mouseX), mapTagReplacements);
6572 // int mouseY; //coords win32Api
6573 gameNode->addAttribute("mouseY",intToStr(mouseY), mapTagReplacements);
6574 // Vec2i mouseCellPos;
6575 gameNode->addAttribute("mouseCellPos",mouseCellPos.getString(), mapTagReplacements);
6576 // int updateFps, lastUpdateFps, avgUpdateFps;
6577 // int totalRenderFps, renderFps, lastRenderFps, avgRenderFps,currentAvgRenderFpsTotal;
6578 //Uint64 tickCount;
6579 gameNode->addAttribute("tickCount",intToStr(tickCount), mapTagReplacements);
6580
6581 //bool paused;
6582 gameNode->addAttribute("paused",intToStr(paused), mapTagReplacements);
6583 //bool gameOver;
6584 gameNode->addAttribute("gameOver",intToStr(gameOver), mapTagReplacements);
6585 //bool renderNetworkStatus;
6586 //bool showFullConsole;
6587 //bool mouseMoved;
6588 //float scrollSpeed;
6589 gameNode->addAttribute("scrollSpeed",floatToStr(scrollSpeed,6), mapTagReplacements);
6590 //bool camLeftButtonDown;
6591 //bool camRightButtonDown;
6592 //bool camUpButtonDown;
6593 //bool camDownButtonDown;
6594
6595 //Speed speed;
6596 gameNode->addAttribute("speed",intToStr(speed), mapTagReplacements);
6597
6598 //GraphicMessageBox mainMessageBox;
6599 //GraphicMessageBox errorMessageBox;
6600
6601 //misc ptr
6602 //ParticleSystem *weatherParticleSystem;
6603 if(weatherParticleSystem != NULL) {
6604 weatherParticleSystem->saveGame(gameNode);
6605 }
6606 //GameSettings gameSettings;
6607 gameSettings.saveGame(gameNode);
6608 //Vec2i lastMousePos;
6609 gameNode->addAttribute("lastMousePos",lastMousePos.getString(), mapTagReplacements);
6610 //time_t lastRenderLog2d;
6611 gameNode->addAttribute("lastRenderLog2d",intToStr(lastRenderLog2d), mapTagReplacements);
6612 //DisplayMessageFunction originalDisplayMsgCallback;
6613 //bool isFirstRender;
6614 gameNode->addAttribute("isFirstRender",intToStr(isFirstRender), mapTagReplacements);
6615
6616 //bool quitTriggeredIndicator;
6617 //int original_updateFps;
6618 gameNode->addAttribute("original_updateFps",intToStr(original_updateFps), mapTagReplacements);
6619 //int original_cameraFps;
6620 gameNode->addAttribute("original_cameraFps",intToStr(original_cameraFps), mapTagReplacements);
6621
6622 //bool captureAvgTestStatus;
6623 gameNode->addAttribute("captureAvgTestStatus",intToStr(captureAvgTestStatus), mapTagReplacements);
6624 //int updateFpsAvgTest;
6625 gameNode->addAttribute("updateFpsAvgTest",intToStr(updateFpsAvgTest), mapTagReplacements);
6626 //int renderFpsAvgTest;
6627 gameNode->addAttribute("renderFpsAvgTest",intToStr(renderFpsAvgTest), mapTagReplacements);
6628
6629 //int renderExtraTeamColor;
6630 gameNode->addAttribute("renderExtraTeamColor",intToStr(renderExtraTeamColor), mapTagReplacements);
6631
6632 //static const int renderTeamColorCircleBit=1;
6633 //static const int renderTeamColorPlaneBit=2;
6634
6635 //bool photoModeEnabled;
6636 gameNode->addAttribute("photoModeEnabled",intToStr(photoModeEnabled), mapTagReplacements);
6637 //bool visibleHUD;
6638 gameNode->addAttribute("visibleHUD",intToStr(visibleHUD), mapTagReplacements);
6639
6640 //bool timeDisplay
6641 gameNode->addAttribute("timeDisplay",intToStr(timeDisplay), mapTagReplacements);
6642
6643 //bool withRainEffect;
6644 gameNode->addAttribute("withRainEffect",intToStr(withRainEffect), mapTagReplacements);
6645 //Program *program;
6646
6647 //bool gameStarted;
6648 gameNode->addAttribute("gameStarted",intToStr(gameStarted), mapTagReplacements);
6649
6650 //time_t lastMaxUnitCalcTime;
6651 gameNode->addAttribute("lastMaxUnitCalcTime",intToStr(lastMaxUnitCalcTime), mapTagReplacements);
6652
6653 //PopupMenu popupMenu;
6654 //PopupMenu popupMenuSwitchTeams;
6655
6656 //std::map<int,int> switchTeamIndexMap;
6657 //GraphicMessageBox switchTeamConfirmMessageBox;
6658
6659 //int exitGamePopupMenuIndex;
6660 //int joinTeamPopupMenuIndex;
6661 //int pauseGamePopupMenuIndex;
6662 //int keyboardSetupPopupMenuIndex;
6663 //GLuint statelist3dMenu;
6664 //ProgramState *currentUIState;
6665
6666 //bool masterserverMode;
6667
6668 //StrSound *currentAmbientSound;
6669
6670 //time_t lastNetworkPlayerConnectionCheck;
6671 gameNode->addAttribute("lastNetworkPlayerConnectionCheck",intToStr(lastNetworkPlayerConnectionCheck), mapTagReplacements);
6672
6673 //time_t lastMasterServerGameStatsDump;
6674 gameNode->addAttribute("lastMasterServerGameStatsDump",intToStr(lastMasterServerGameStatsDump), mapTagReplacements);
6675
6676 XmlNode *unitHighlightListNode = gameNode->addChild("unitHighlightList");
6677 //for(unsigned int i = 0; i < unitHighlightList.size(); ++i) {
6678 for(std::map<int,HighlightSpecialUnitInfo>::iterator iterMap = unitHighlightList.begin();
6679 iterMap != unitHighlightList.end(); ++iterMap) {
6680 HighlightSpecialUnitInfo &info = iterMap->second;
6681 XmlNode *infoNode = unitHighlightListNode->addChild("info");
6682 infoNode->addAttribute("unitid",intToStr(iterMap->first), mapTagReplacements);
6683 infoNode->addAttribute("radius",floatToStr(info.radius,6), mapTagReplacements);
6684 infoNode->addAttribute("thickness",floatToStr(info.thickness,6), mapTagReplacements);
6685 infoNode->addAttribute("color",info.color.getString(), mapTagReplacements);
6686 }
6687
6688 gameNode->addAttribute("disableSpeedChange",intToStr(disableSpeedChange), mapTagReplacements);
6689
6690 xmlTree.save(saveGameFile);
6691
6692 if(masterserverMode == false) {
6693 // take Screenshot
6694 string jpgFileName=saveGameFile+".jpg";
6695 // menu is already disabled, last rendered screen is still with enabled one. Lets render again:
6696 render3d();
6697 render2d();
6698 Renderer::getInstance().saveScreen(jpgFileName,config.getInt("SaveGameScreenshotWidth","800"),config.getInt("SaveGameScreenshotHeight","600"));
6699 }
6700
6701 return saveGameFile;
6702 }
6703
6704 void Game::loadGame(string name,Program *programPtr,bool isMasterserverMode,const GameSettings *joinGameSettings) {
6705 Config &config= Config::getInstance();
6706 // This condition will re-play all the commands from a replay file
6707 // INSTEAD of saving from a saved game.
6708 if(joinGameSettings == NULL && config.getBool("SaveCommandsForReplay","false") == true) {
6709 XmlTree xmlTreeReplay(XML_RAPIDXML_ENGINE);
6710 std::map<string,string> mapExtraTagReplacementValues;
6711 xmlTreeReplay.load(name + ".replay", Properties::getTagReplacementValues(&mapExtraTagReplacementValues),true);
6712
6713 const XmlNode *rootNode= xmlTreeReplay.getRootNode();
6714
6715 if(rootNode->hasChild("megaglest-saved-game") == true) {
6716 rootNode = rootNode->getChild("megaglest-saved-game");
6717 }
6718
6719 //const XmlNode *versionNode= rootNode->getChild("megaglest-saved-game");
6720 const XmlNode *versionNode= rootNode;
6721
6722 Lang &lang= Lang::getInstance();
6723 string gameVer = versionNode->getAttribute("version")->getValue();
6724 if(gameVer != glestVersionString && checkVersionComptability(gameVer, glestVersionString) == false){
6725 char szBuf[8096]="";
6726 snprintf(szBuf,8096,lang.getString("SavedGameBadVersion").c_str(),gameVer.c_str(),glestVersionString.c_str());
6727 throw megaglest_runtime_error(szBuf,true);
6728 }
6729
6730 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Found saved game version that matches your application version: [%s] --> [%s]\n",gameVer.c_str(),glestVersionString.c_str());
6731
6732 XmlNode *gameNode = rootNode->getChild("Game");
6733
6734 GameSettings newGameSettingsReplay;
6735 newGameSettingsReplay.loadGame(gameNode);
6736 //printf("Loading scenario [%s]\n",newGameSettingsReplay.getScenarioDir().c_str());
6737 if(newGameSettingsReplay.getScenarioDir() != "" && fileExists(newGameSettingsReplay.getScenarioDir()) == false) {
6738 newGameSettingsReplay.setScenarioDir(Scenario::getScenarioPath(Config::getInstance().getPathListForType(ptScenarios),newGameSettingsReplay.getScenario()));
6739
6740 //printf("Loading scenario #2 [%s]\n",newGameSettingsReplay.getScenarioDir().c_str());
6741 }
6742
6743 //GameSettings newGameSettings;
6744 //newGameSettings.loadGame(gameNode);
6745 //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Game settings loaded\n");
6746
6747 NetworkManager &networkManager= NetworkManager::getInstance();
6748 networkManager.end();
6749 networkManager.init(nrServer,true);
6750
6751 Game *newGame = new Game(programPtr, &newGameSettingsReplay, isMasterserverMode);
6752 newGame->lastworldFrameCountForReplay = gameNode->getAttribute("LastWorldFrameCount")->getIntValue();
6753
6754 vector<XmlNode *> networkCommandNodeList = gameNode->getChildList("NetworkCommand");
6755 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("networkCommandNodeList.size() = " MG_SIZE_T_SPECIFIER "\n",networkCommandNodeList.size());
6756 for(unsigned int i = 0; i < networkCommandNodeList.size(); ++i) {
6757 XmlNode *node = networkCommandNodeList[i];
6758 int worldFrameCount = node->getAttribute("worldFrameCount")->getIntValue();
6759 NetworkCommand command;
6760 command.loadGame(node);
6761 newGame->commander.addToReplayCommandList(command,worldFrameCount);
6762 }
6763
6764 programPtr->setState(newGame);
6765 return;
6766 }
6767
6768 XmlTree xmlTree(XML_RAPIDXML_ENGINE);
6769
6770 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Before load of XML\n");
6771 std::map<string,string> mapExtraTagReplacementValues;
6772 xmlTree.load(name, Properties::getTagReplacementValues(&mapExtraTagReplacementValues),true);
6773 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("After load of XML\n");
6774
6775 const XmlNode *rootNode= xmlTree.getRootNode();
6776 if(rootNode->hasChild("megaglest-saved-game") == true) {
6777 rootNode = rootNode->getChild("megaglest-saved-game");
6778 }
6779
6780 //const XmlNode *versionNode= rootNode->getChild("megaglest-saved-game");
6781 const XmlNode *versionNode= rootNode;
6782
6783 Lang &lang= Lang::getInstance();
6784 string gameVer = versionNode->getAttribute("version")->getValue();
6785 // this is the version check for loading normal save games from menu_state_load_game
6786 if (gameVer != glestVersionString
6787 && (compareMajorMinorVersion(gameVer, lastCompatibleSaveGameVersionString) < 0
6788 || compareMajorMinorVersion(glestVersionString, gameVer) < 0)) {
6789 char szBuf[8096]="";
6790 snprintf(szBuf,8096,lang.getString("SavedGameBadVersion").c_str(),gameVer.c_str(),glestVersionString.c_str());
6791 throw megaglest_runtime_error(szBuf,true);
6792 }
6793
6794 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Found saved game version that matches your application version: [%s] --> [%s]\n",gameVer.c_str(),glestVersionString.c_str());
6795
6796 XmlNode *gameNode = rootNode->getChild("Game");
6797 GameSettings newGameSettings;
6798 if(joinGameSettings != NULL) {
6799 newGameSettings = *joinGameSettings;
6800
6801 XmlNode *worldNode = gameNode->getChild("World");
6802 XmlNode *guiNode = gameNode->getChild("Gui");
6803 XmlNode *selectionNode = guiNode->getChild("Selection");
6804 XmlNode *statsNode = worldNode->getChild("Stats");
6805 XmlNode *minimapNode = worldNode->getChild("Minimap");
6806
6807 if(gameVer != glestVersionString && checkVersionComptability(gameVer, glestVersionString) == false){
6808 char szBuf[8096]="";
6809 snprintf(szBuf,8096,lang.getString("SavedGameBadVersion").c_str(),gameVer.c_str(),glestVersionString.c_str());
6810 throw megaglest_runtime_error(szBuf,true);
6811 }
6812 // This is explored fog of war for the host player, clear it
6813 minimapNode->clearChild("fowPixmap1");
6814
6815 NetworkManager &networkManager= NetworkManager::getInstance();
6816 //NetworkRole role = networkManager.getNetworkRole();
6817 ClientInterface *clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
6818
6819 for(int i= 0; i<newGameSettings.getFactionCount(); ++i) {
6820 //replace by network
6821 if(newGameSettings.getFactionControl(i)==ctHuman) {
6822 newGameSettings.setFactionControl(i, ctNetwork);
6823 }
6824
6825 //set the faction index
6826 if(newGameSettings.getStartLocationIndex(i) == clientInterface->getPlayerIndex()) {
6827 newGameSettings.setThisFactionIndex(i);
6828 newGameSettings.setFactionControl(i, ctNetwork);
6829
6830 worldNode->getAttribute("thisFactionIndex")->setValue(intToStr(i));
6831 //worldNode->getAttribute("thisTeamIndex")->setValue(intToStr(newGameSettings.getTeam(i)));
6832
6833 XmlNode *factionNode = worldNode->getChild("Faction",i);
6834 factionNode->getAttribute("thisFaction")->setValue(intToStr(i));
6835 factionNode->getAttribute("control")->setValue(intToStr(ctNetwork));
6836
6837 selectionNode->getAttribute("factionIndex")->setValue(intToStr(i));
6838 //selectionNode->getAttribute("teamIndex")->setValue(intToStr(newGameSettings.getTeam(i)));
6839
6840 statsNode->getAttribute("thisFactionIndex")->setValue(intToStr(i));
6841 }
6842 else {
6843 XmlNode *factionNode = worldNode->getChild("Faction",i);
6844 factionNode->getAttribute("thisFaction")->setValue(intToStr(0));
6845 }
6846 }
6847 }
6848 else {
6849 newGameSettings.loadGame(gameNode);
6850 //printf("Loading scenario [%s]\n",newGameSettings.getScenarioDir().c_str());
6851 if(newGameSettings.getScenarioDir() != "" && fileExists(newGameSettings.getScenarioDir()) == false) {
6852 newGameSettings.setScenarioDir(Scenario::getScenarioPath(Config::getInstance().getPathListForType(ptScenarios),newGameSettings.getScenario()));
6853
6854 //printf("Loading scenario #2 [%s]\n",newGameSettings.getScenarioDir().c_str());
6855 }
6856 }
6857
6858 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Game settings loaded\n");
6859
6860 if(joinGameSettings == NULL) {
6861 NetworkManager &networkManager= NetworkManager::getInstance();
6862 networkManager.end();
6863 networkManager.init(nrServer,true);
6864 }
6865
6866 Game *newGame = new Game(programPtr, &newGameSettings, isMasterserverMode);
6867
6868 newGame->loadGameNode = gameNode;
6869 newGame->inJoinGameLoading = (joinGameSettings != NULL);
6870
6871 // newGame->mouse2d = gameNode->getAttribute("mouse2d")->getIntValue();
6872 // int mouseX;
6873 // newGame->mouseX = gameNode->getAttribute("mouseX")->getIntValue();
6874 // int mouseY; //coords win32Api
6875 // newGame->mouseY = gameNode->getAttribute("mouseY")->getIntValue();
6876 // Vec2i mouseCellPos;
6877 // newGame->mouseCellPos = Vec2i::strToVec2(gameNode->getAttribute("mouseCellPos")->getValue());
6878 // int updateFps, lastUpdateFps, avgUpdateFps;
6879 // int totalRenderFps, renderFps, lastRenderFps, avgRenderFps,currentAvgRenderFpsTotal;
6880 //Uint64 tickCount;
6881 newGame->tickCount = gameNode->getAttribute("tickCount")->getIntValue();
6882
6883 //bool paused;
6884 if(newGame->inJoinGameLoading==true){
6885 newGame->paused = gameNode->getAttribute("paused")->getIntValue() != 0;
6886 }else{
6887 //newGame->paused = gameNode->getAttribute("paused")->getIntValue() != 0;
6888 newGame->paused = true;
6889 }
6890 if(newGame->paused) newGame->console.addLine(lang.getString("GamePaused"));
6891 //bool gameOver;
6892 newGame->gameOver = gameNode->getAttribute("gameOver")->getIntValue() != 0;
6893 //bool renderNetworkStatus;
6894 //bool showFullConsole;
6895 //bool mouseMoved;
6896 //float scrollSpeed;
6897 // newGame->scrollSpeed = gameNode->getAttribute("scrollSpeed")->getFloatValue();
6898 //bool camLeftButtonDown;
6899 //bool camRightButtonDown;
6900 //bool camUpButtonDown;
6901 //bool camDownButtonDown;
6902
6903 //Speed speed;
6904 //gameNode->addAttribute("speed",intToStr(speed), mapTagReplacements);
6905
6906 //GraphicMessageBox mainMessageBox;
6907 //GraphicMessageBox errorMessageBox;
6908
6909 //misc ptr
6910 //ParticleSystem *weatherParticleSystem;
6911 // if(weatherParticleSystem != NULL) {
6912 // weatherParticleSystem->saveGame(gameNode);
6913 // }
6914 //GameSettings gameSettings;
6915 // gameSettings.saveGame(gameNode);
6916 //Vec2i lastMousePos;
6917 // gameNode->addAttribute("lastMousePos",lastMousePos.getString(), mapTagReplacements);
6918 //time_t lastRenderLog2d;
6919 // gameNode->addAttribute("lastRenderLog2d",intToStr(lastRenderLog2d), mapTagReplacements);
6920 //DisplayMessageFunction originalDisplayMsgCallback;
6921 //bool isFirstRender;
6922 // gameNode->addAttribute("isFirstRender",intToStr(isFirstRender), mapTagReplacements);
6923
6924 //bool quitTriggeredIndicator;
6925 //int original_updateFps;
6926 // gameNode->addAttribute("original_updateFps",intToStr(original_updateFps), mapTagReplacements);
6927 //int original_cameraFps;
6928 // gameNode->addAttribute("original_cameraFps",intToStr(original_cameraFps), mapTagReplacements);
6929
6930 //bool captureAvgTestStatus;
6931 // gameNode->addAttribute("captureAvgTestStatus",intToStr(captureAvgTestStatus), mapTagReplacements);
6932 //int updateFpsAvgTest;
6933 // gameNode->addAttribute("updateFpsAvgTest",intToStr(updateFpsAvgTest), mapTagReplacements);
6934 //int renderFpsAvgTest;
6935 // gameNode->addAttribute("renderFpsAvgTest",intToStr(renderFpsAvgTest), mapTagReplacements);
6936
6937 //int renderExtraTeamColor;
6938 newGame->renderExtraTeamColor = gameNode->getAttribute("renderExtraTeamColor")->getIntValue();
6939
6940 //static const int renderTeamColorCircleBit=1;
6941 //static const int renderTeamColorPlaneBit=2;
6942
6943 //bool photoModeEnabled;
6944 //gameNode->addAttribute("photoModeEnabled",intToStr(photoModeEnabled), mapTagReplacements);
6945 newGame->photoModeEnabled = gameNode->getAttribute("photoModeEnabled")->getIntValue() != 0;
6946 //bool visibleHUD;
6947 //gameNode->addAttribute("visibleHUD",intToStr(visibleHUD), mapTagReplacements);
6948 newGame->visibleHUD = gameNode->getAttribute("visibleHUD")->getIntValue() != 0;
6949 newGame->timeDisplay = gameNode->getAttribute("timeDisplay")->getIntValue() != 0;
6950 //bool withRainEffect;
6951 //gameNode->addAttribute("withRainEffect",intToStr(withRainEffect), mapTagReplacements);
6952 newGame->withRainEffect = gameNode->getAttribute("withRainEffect")->getIntValue() != 0;
6953 //Program *program;
6954
6955 if(joinGameSettings == NULL) {
6956 if(gameNode->hasChild("unitHighlightList") == true) {
6957 XmlNode *unitHighlightListNode = gameNode->getChild("unitHighlightList");
6958 vector<XmlNode *> infoNodeList = unitHighlightListNode->getChildList("info");
6959 for(unsigned int i = 0; i < infoNodeList.size(); ++i) {
6960 XmlNode *infoNode = infoNodeList[i];
6961
6962 int unitId = infoNode->getAttribute("radius")->getIntValue();
6963 HighlightSpecialUnitInfo info;
6964 info.radius = infoNode->getAttribute("radius")->getFloatValue();
6965 info.thickness = infoNode->getAttribute("thickness")->getFloatValue();
6966 info.color = Vec4f::strToVec4(infoNode->getAttribute("color")->getValue());
6967
6968 newGame->unitHighlightList[unitId] = info;
6969 }
6970 }
6971 }
6972
6973 newGame->timeDisplay = gameNode->getAttribute("timeDisplay")->getIntValue() != 0;
6974
6975 if(gameNode->hasAttribute("disableSpeedChange") == true) {
6976 newGame->disableSpeedChange = gameNode->getAttribute("disableSpeedChange")->getIntValue() != 0;
6977 }
6978
6979 //bool gameStarted;
6980 //gameNode->addAttribute("gameStarted",intToStr(gameStarted), mapTagReplacements);
6981 // newGame->gameStarted = gameNode->getAttribute("gameStarted")->getIntValue();
6982
6983 //time_t lastMaxUnitCalcTime;
6984 //gameNode->addAttribute("lastMaxUnitCalcTime",intToStr(lastMaxUnitCalcTime), mapTagReplacements);
6985
6986 //PopupMenu popupMenu;
6987 //PopupMenu popupMenuSwitchTeams;
6988
6989 //std::map<int,int> switchTeamIndexMap;
6990 //GraphicMessageBox switchTeamConfirmMessageBox;
6991
6992 //int exitGamePopupMenuIndex;
6993 //int joinTeamPopupMenuIndex;
6994 //int pauseGamePopupMenuIndex;
6995 //int keyboardSetupPopupMenuIndex;
6996 //GLuint statelist3dMenu;
6997 //ProgramState *currentUIState;
6998
6999 //bool masterserverMode;
7000
7001 //StrSound *currentAmbientSound;
7002
7003 //time_t lastNetworkPlayerConnectionCheck;
7004 //gameNode->addAttribute("lastNetworkPlayerConnectionCheck",intToStr(lastNetworkPlayerConnectionCheck), mapTagReplacements);
7005
7006 //time_t lastMasterServerGameStatsDump;
7007 //gameNode->addAttribute("lastMasterServerGameStatsDump",intToStr(lastMasterServerGameStatsDump), mapTagReplacements);
7008
7009 if(joinGameSettings == NULL) {
7010 newGame->gameCamera.loadGame(gameNode);
7011 }
7012
7013 const XmlNode *worldNode = gameNode->getChild("World");
7014 newGame->world.loadGame(worldNode);
7015 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Starting Game ...\n");
7016 programPtr->setState(newGame);
7017 }
7018
7019 }}//end namespace
7020