MegaGlest/source/glest_game/game/game.cpp
titiger 2efa255ca3 no more double click in minimap
Double  click is no more handled when mousepointer is over minimap.
This often resulted in unselected units when commanding via minimap.
2015-01-29 11:42:13 +01:00

7010 lines
272 KiB
C++

// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "game.h"
#include "config.h"
#include "renderer.h"
#include "particle_renderer.h"
#include "commander.h"
#include "battle_end.h"
#include "sound_renderer.h"
#include "profiler.h"
#include "core_data.h"
#include "metrics.h"
#include "faction.h"
#include "network_manager.h"
#include "checksum.h"
#include "auto_test.h"
#include "menu_state_keysetup.h"
#include "video_player.h"
#include "compression_utils.h"
#include "cache_manager.h"
#include "leak_dumper.h"
using namespace Shared::Graphics;
using namespace Shared::Util;
using namespace Shared::Platform;
using namespace Shared::CompressionUtil;
namespace Glest{ namespace Game{
string GameSettings::playerDisconnectedText = "";
Game *thisGamePtr = NULL;
// =====================================================
// class Game
// =====================================================
// ===================== PUBLIC ========================
const float PHOTO_MODE_MAXHEIGHT = 500.0;
const int CREATE_NEW_TEAM = -100;
const int CANCEL_SWITCH_TEAM = -1;
const int CANCEL_DISCONNECT_PLAYER = -1;
const float Game::highlightTime= 0.5f;
int fadeMusicMilliseconds = 3500;
// Check every x seconds if we should switch disconnected players to AI
const int NETWORK_PLAYER_CONNECTION_CHECK_SECONDS = 5;
int GAME_STATS_DUMP_INTERVAL = 60 * 10;
Game::Game() : ProgramState(NULL) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
originalDisplayMsgCallback = NULL;
aiInterfaces.clear();
videoPlayer = NULL;
playingStaticVideo = false;
mouse2d=0;
mouseX=0;
mouseY=0;
updateFps=0;
lastUpdateFps=0;
avgUpdateFps=0;
framesToCatchUpAsClient=0;
framesToSlowDownAsClient=0;
totalRenderFps=0;
renderFps=0;
lastRenderFps=0;
avgRenderFps=0;
currentAvgRenderFpsTotal=0;
paused=false;
networkPauseGameForLaggedClientsRequested=false;
networkResumeGameForLaggedClientsRequested=false;
pausedForJoinGame=false;
pausedBeforeJoinGame=false;
pauseRequestSent=false;
resumeRequestSent=false;
pauseStateChanged=false;
gameOver=false;
renderNetworkStatus=false;
renderInGamePerformance=false;
showFullConsole=false;
setMarker=false;
cameraDragAllowed=false;
mouseMoved=false;
scrollSpeed=0;
camLeftButtonDown=false;
camRightButtonDown=false;
camUpButtonDown=false;
camDownButtonDown=false;
this->speed=1;
weatherParticleSystem=NULL;
isFirstRender=false;
quitTriggeredIndicator=false;
quitPendingIndicator=false;
original_updateFps=0;
original_cameraFps=0;
captureAvgTestStatus=false;
updateFpsAvgTest=0;
renderFpsAvgTest=0;
renderExtraTeamColor=0;
photoModeEnabled=false;
healthbarMode=hbvUndefined;
visibleHUD=false;
timeDisplay=false;
withRainEffect=false;
program=NULL;
gameStarted=false;
this->initialResumeSpeedLoops=false;
highlightCellTexture=NULL;
lastMasterServerGameStatsDump=0;
lastMaxUnitCalcTime=0;
lastRenderLog2d=0;
playerIndexDisconnect=0;
tickCount=0;
currentCameraFollowUnit=NULL;
popupMenu.setEnabled(false);
popupMenu.setVisible(false);
popupMenuSwitchTeams.setEnabled(false);
popupMenuSwitchTeams.setVisible(false);
popupMenuDisconnectPlayer.setEnabled(false);
popupMenuDisconnectPlayer.setVisible(false);
switchTeamConfirmMessageBox.setEnabled(false);
disconnectPlayerConfirmMessageBox.setEnabled(false);
disconnectPlayerIndexMap.clear();
exitGamePopupMenuIndex = -1;
joinTeamPopupMenuIndex = -1;
pauseGamePopupMenuIndex = -1;
saveGamePopupMenuIndex = -1;
loadGamePopupMenuIndex = -1;
keyboardSetupPopupMenuIndex = -1;
disconnectPlayerPopupMenuIndex = -1;
isMarkCellEnabled = false;
isMarkCellTextEnabled = false;
markCellTexture = NULL;
isUnMarkCellEnabled = false;
unmarkCellTexture = NULL;
masterserverMode = false;
currentUIState=NULL;
currentAmbientSound=NULL;
//printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
loadGameNode = NULL;
lastworldFrameCountForReplay = -1;
lastNetworkPlayerConnectionCheck = time(NULL);
inJoinGameLoading = false;
quitGameCalled = false;
disableSpeedChange = false;
for( int i=0;i<GameConstants::networkSmoothInterval;i++){
receivedTooEarlyInFrames[i]=-1;
framesNeededToWaitForServerMessage[i]=-1;
}
fadeMusicMilliseconds = Config::getInstance().getInt("GameStartStopFadeSoundMilliseconds",intToStr(fadeMusicMilliseconds).c_str());
GAME_STATS_DUMP_INTERVAL = Config::getInstance().getInt("GameStatsDumpIntervalSeconds",intToStr(GAME_STATS_DUMP_INTERVAL).c_str());
}
void Game::resetMembers() {
Unit::setGame(this);
gameStarted = false;
this->initialResumeSpeedLoops = false;
original_updateFps = GameConstants::updateFps;
original_cameraFps = GameConstants::cameraFps;
GameConstants::updateFps= 40;
GameConstants::cameraFps= 100;
captureAvgTestStatus = false;
updateFpsAvgTest=0;
renderFpsAvgTest=0;
lastRenderLog2d = 0;
playerIndexDisconnect=0;
lastMasterServerGameStatsDump=0;
highlightCellTexture=NULL;
totalRenderFps =0;
lastMaxUnitCalcTime =0;
renderExtraTeamColor =0;
mouseMoved= false;
quitTriggeredIndicator = false;
quitPendingIndicator=false;
originalDisplayMsgCallback = NULL;
thisGamePtr = this;
popupMenu.setEnabled(false);
popupMenu.setVisible(false);
popupMenuSwitchTeams.setEnabled(false);
popupMenuSwitchTeams.setVisible(false);
popupMenuDisconnectPlayer.setEnabled(false);
popupMenuDisconnectPlayer.setVisible(false);
switchTeamConfirmMessageBox.setEnabled(false);
disconnectPlayerConfirmMessageBox.setEnabled(false);
disconnectPlayerIndexMap.clear();
exitGamePopupMenuIndex = -1;
joinTeamPopupMenuIndex = -1;
pauseGamePopupMenuIndex = -1;
saveGamePopupMenuIndex = -1;
loadGamePopupMenuIndex = -1;
keyboardSetupPopupMenuIndex = -1;
disconnectPlayerPopupMenuIndex = -1;
isMarkCellEnabled = false;
isMarkCellTextEnabled = false;
markCellTexture = NULL;
isUnMarkCellEnabled = false;
unmarkCellTexture = NULL;
currentUIState = NULL;
scrollSpeed = Config::getInstance().getFloat("UiScrollSpeed","1.5");
photoModeEnabled = Config::getInstance().getBool("PhotoMode","false");
healthbarMode = Config::getInstance().getInt("HealthBarMode","4");
visibleHUD = Config::getInstance().getBool("VisibleHud","true");
timeDisplay = Config::getInstance().getBool("TimeDisplay","true");
withRainEffect = Config::getInstance().getBool("RainEffect","true");
//MIN_RENDER_FPS_ALLOWED = Config::getInstance().getInt("MIN_RENDER_FPS_ALLOWED",intToStr(MIN_RENDER_FPS_ALLOWED).c_str());
mouseX=0;
mouseY=0;
mouse2d= 0;
loadingText="";
weatherParticleSystem= NULL;
updateFps=0;
renderFps=0;
lastUpdateFps=0;
framesToCatchUpAsClient=0;
framesToSlowDownAsClient=0;
lastRenderFps=-1;
avgUpdateFps=-1;
avgRenderFps=-1;
currentAvgRenderFpsTotal=0;
tickCount=0;
paused= false;
networkPauseGameForLaggedClientsRequested=false;
networkResumeGameForLaggedClientsRequested=false;
pausedForJoinGame=false;
pausedBeforeJoinGame=false;
resumeRequestSent=false;
pauseRequestSent=false;
pauseStateChanged=false;
gameOver= false;
renderNetworkStatus= false;
renderInGamePerformance=false;
this->speed= 1;
showFullConsole= false;
setMarker = false;
cameraDragAllowed=false;
camLeftButtonDown=false;
camRightButtonDown=false;
camUpButtonDown=false;
camDownButtonDown=false;
currentCameraFollowUnit=NULL;
currentAmbientSound=NULL;
//printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
loadGameNode = NULL;
lastworldFrameCountForReplay = -1;
lastNetworkPlayerConnectionCheck = time(NULL);
inJoinGameLoading = false;
quitGameCalled = false;
disableSpeedChange = false;
for( int i=0;i<GameConstants::networkSmoothInterval;i++){
receivedTooEarlyInFrames[i]=-1;
framesNeededToWaitForServerMessage[i]=-1;
}
fadeMusicMilliseconds = Config::getInstance().getInt("GameStartStopFadeSoundMilliseconds",intToStr(fadeMusicMilliseconds).c_str());
GAME_STATS_DUMP_INTERVAL = Config::getInstance().getInt("GameStatsDumpIntervalSeconds",intToStr(GAME_STATS_DUMP_INTERVAL).c_str());
Logger &logger= Logger::getInstance();
logger.showProgress();
}
Game::Game(Program *program, const GameSettings *gameSettings,bool masterserverMode):
ProgramState(program), lastMousePos(0), isFirstRender(true)
{
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
this->masterserverMode = masterserverMode;
videoPlayer = NULL;
playingStaticVideo = false;
highlightCellTexture = NULL;
playerIndexDisconnect=0;
updateFpsAvgTest=0;
renderFpsAvgTest=0;
cameraDragAllowed=false;
if(this->masterserverMode == true) {
printf("Starting a new game...\n");
}
this->program = program;
resetMembers();
this->gameSettings= *gameSettings;
Lang::getInstance().setAllowNativeLanguageTechtree(this->gameSettings.getNetworkAllowNativeLanguageTechtree());
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
}
void Game::endGame() {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
quitGame();
sleep(0);
Object::setStateCallback(NULL);
thisGamePtr = NULL;
if(originalDisplayMsgCallback != NULL) {
NetworkInterface::setDisplayMessageFunction(originalDisplayMsgCallback);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
Logger &logger= Logger::getInstance();
Renderer &renderer= Renderer::getInstance();
logger.clearHints();
logger.loadLoadingScreen("");
logger.setState(Lang::getInstance().getString("Deleting"));
//logger.add("Game", true);
logger.add(Lang::getInstance().getString("LogScreenGameLoading","",true), false);
logger.hideProgress();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// Cannot Fade because sound files will be deleted below
SoundRenderer::getInstance().stopAllSounds(fadeMusicMilliseconds);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// deleteValues(aiInterfaces.begin(), aiInterfaces.end());
// aiInterfaces.clear();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
gui.end(); //selection must be cleared before deleting units
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// world.end(); //must die before selection because of referencers
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());
// MUST DO THIS LAST!!!! Because objects above have pointers to things like
// unit particles and fade them out etc and this end method deletes the original
// object pointers.
renderer.endGame(false);
GameConstants::updateFps = original_updateFps;
GameConstants::cameraFps = original_cameraFps;
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
Unit::setGame(NULL);
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"==== END GAME ====\n");
FileCRCPreCacheThread * &preCacheCRCThreadPtr = CacheManager::getCachedItem< FileCRCPreCacheThread * >(GameConstants::preCacheThreadCacheLookupKey);
if(preCacheCRCThreadPtr != NULL) {
preCacheCRCThreadPtr->setPauseForGame(false);
}
//this->program->reInitGl();
//renderer.reinitAll();
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
}
Game::~Game() {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
quitGame();
Object::setStateCallback(NULL);
thisGamePtr = NULL;
if(originalDisplayMsgCallback != NULL) {
NetworkInterface::setDisplayMessageFunction(originalDisplayMsgCallback);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
Logger &logger= Logger::getInstance();
Renderer &renderer= Renderer::getInstance();
logger.loadLoadingScreen("");
logger.setState(Lang::getInstance().getString("Deleting"));
//logger.add("Game", true);
logger.add(Lang::getInstance().getString("LogScreenGameLoading","",true), false);
logger.hideProgress();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// Cannot Fade because sound files will be deleted below
SoundRenderer::getInstance().stopAllSounds();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
masterController.clearSlaves(true);
deleteValues(aiInterfaces.begin(), aiInterfaces.end());
aiInterfaces.clear();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
gui.end(); //selection must be cleared before deleting units
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
world.end(); //must die before selection because of referencers
BaseColorPickEntity::resetUniqueColors();
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());
delete videoPlayer;
videoPlayer = NULL;
playingStaticVideo = false;
// MUST DO THIS LAST!!!! Because objects above have pointers to things like
// unit particles and fade them out etc and this end method deletes the original
// object pointers.
renderer.endGame(true);
BaseColorPickEntity::cleanupPBO();
GameConstants::updateFps = original_updateFps;
GameConstants::cameraFps = original_cameraFps;
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
Unit::setGame(NULL);
Lang::getInstance().setAllowNativeLanguageTechtree(true);
FileCRCPreCacheThread * &preCacheCRCThreadPtr = CacheManager::getCachedItem< FileCRCPreCacheThread * >(GameConstants::preCacheThreadCacheLookupKey);
if(preCacheCRCThreadPtr != NULL) {
preCacheCRCThreadPtr->setPauseForGame(false);
}
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"==== END GAME ====\n");
//this->program->reInitGl();
//renderer.reinitAll();
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
}
bool Game::showTranslatedTechTree() const {
return this->gameSettings.getNetworkAllowNativeLanguageTechtree();
}
bool Game::quitTriggered() {
return quitTriggeredIndicator;
}
Stats Game::quitAndToggleState() {
//quitGame();
//Program *program = game->getProgram();
return quitGame();
//Game::exitGameState(program, endStats);
}
// ==================== init and load ====================
int Game::ErrorDisplayMessage(const char *msg, bool exitApp) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,msg);
if(thisGamePtr != NULL) {
string text = msg;
thisGamePtr->showErrorMessageBox(text, "Error detected", false);
}
return 0;
}
Texture2D * Game::findFactionLogoTexture(const GameSettings *settings, Logger *logger,string factionLogoFilter, bool useTechDefaultIfFilterNotFound) {
Texture2D *result = NULL;
string logoFilename = Game::findFactionLogoFile(settings, logger,factionLogoFilter);
if(logoFilename == "" && factionLogoFilter != "" && useTechDefaultIfFilterNotFound == true) {
logoFilename = Game::findFactionLogoFile(settings, logger);
}
result = Renderer::findTexture(logoFilename);
return result;
}
string Game::extractScenarioLogoFile(const GameSettings *settings, string &result,
bool &loadingImageUsed, Logger *logger, string factionLogoFilter) {
string scenarioDir = "";
if(settings->getScenarioDir() != "") {
scenarioDir = settings->getScenarioDir();
if(EndsWith(scenarioDir, ".xml") == true) {
scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4);
scenarioDir = scenarioDir.erase(scenarioDir.size() - settings->getScenario().size(), settings->getScenario().size() + 1);
}
//printf("!!! extractScenarioLogoFile scenarioDir [%s] factionLogoFilter [%s]\n",scenarioDir.c_str(),factionLogoFilter.c_str());
vector<string> loadScreenList;
string logoFullPathFilter = scenarioDir + factionLogoFilter;
findAll(logoFullPathFilter, loadScreenList, false, false);
if(loadScreenList.empty() == false) {
int bestLogoIndex = 0;
if(loadScreenList.size() > 1 && EndsWith(factionLogoFilter, ".xml") == false) {
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());
int bestMinWidthDiff = INT_MAX;
int bestMinHeightDiff = INT_MAX;
// Now find the best texture for our screen
// Texture2D *result = preloadTexture(logoFilename);
for(unsigned int logoIndex = 0; logoIndex < loadScreenList.size(); ++logoIndex) {
string senarioLogo = scenarioDir + loadScreenList[bestLogoIndex];
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());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Looking for best logo: %u [%s]\n",logoIndex,senarioLogo.c_str());
if(fileExists(senarioLogo) == true) {
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());
Texture2D *checkLogo = Renderer::preloadTexture(senarioLogo);
if(checkLogo != NULL) {
const Metrics &metrics= Metrics::getInstance();
int minWidthDifference = abs(metrics.getScreenW() - checkLogo->getPixmapConst()->getW());
int minHeightDifference = abs(metrics.getScreenH() - checkLogo->getPixmapConst()->getH());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Logo info: %d x %d (%d,%d)\n",checkLogo->getPixmapConst()->getW(),checkLogo->getPixmapConst()->getH(),minWidthDifference,minHeightDifference);
if(minWidthDifference < bestMinWidthDiff) {
bestMinWidthDiff = minWidthDifference;
bestLogoIndex = logoIndex;
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 New best logo is [%s]\n",senarioLogo.c_str());
}
else if(minWidthDifference == bestMinWidthDiff &&
minHeightDifference < bestMinHeightDiff) {
bestMinHeightDiff = minHeightDifference;
bestLogoIndex = logoIndex;
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 New best logo is [%s]\n",senarioLogo.c_str());
}
}
}
}
}
string senarioLogo = scenarioDir + loadScreenList[bestLogoIndex];
if(fileExists(senarioLogo) == true) {
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());
result = senarioLogo;
if(logger != NULL) {
logger->loadLoadingScreen(result);
}
loadingImageUsed=true;
}
}
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());
}
return scenarioDir;
}
string Game::extractFactionLogoFile(bool &loadingImageUsed, string factionName,
string scenarioDir, string techName, Logger *logger, string factionLogoFilter) {
string result = "";
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__);
if(factionName == formatString(GameConstants::OBSERVER_SLOTNAME)) {
string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
const string factionLogo = data_path + "data/core/misc_textures/observer.jpg";
//printf("In [%s::%s Line: %d] looking for loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,factionLogo.c_str());
if(fileExists(factionLogo) == true) {
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());
result = factionLogo;
if(logger != NULL) {
logger->loadLoadingScreen(result);
}
loadingImageUsed = true;
}
}
//else if(settings->getFactionTypeName(i) == formatString(GameConstants::RANDOMFACTION_SLOTNAME)) {
else if(factionName == formatString(GameConstants::RANDOMFACTION_SLOTNAME)) {
string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
const string factionLogo = data_path + "data/core/misc_textures/random.jpg";
if(fileExists(factionLogo) == true) {
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());
result = factionLogo;
if(logger != NULL) {
logger->loadLoadingScreen(result);
}
loadingImageUsed = true;
}
}
else {
Config &config = Config::getInstance();
vector<string> pathList = config.getPathListForType(ptTechs,scenarioDir);
for(int idx = 0; idx < (int)pathList.size(); idx++) {
string currentPath = pathList[idx];
endPathWithSlash(currentPath);
//string path = currentPath + techName + "/" + "factions" + "/" + settings->getFactionTypeName(i);
string path = currentPath + techName + "/" + "factions" + "/" + factionName;
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());
if(isdir(path.c_str()) == true) {
endPathWithSlash(path);
vector<string> loadScreenList;
string logoFullPathFilter = path + factionLogoFilter;
findAll(logoFullPathFilter, loadScreenList, false, false);
if(loadScreenList.empty() == false) {
int bestLogoIndex = 0;
if(loadScreenList.size() > 1 && EndsWith(factionLogoFilter, ".xml") == false) {
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());
int bestMinWidthDiff = INT_MAX;
int bestMinHeightDiff = INT_MAX;
// Now find the best texture for our screen
// Texture2D *result = preloadTexture(logoFilename);
for(unsigned int logoIndex = 0; logoIndex < (unsigned int)loadScreenList.size(); ++logoIndex) {
string factionLogo = path + loadScreenList[logoIndex];
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());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Looking for best logo: %u [%s]\n",logoIndex,factionLogo.c_str());
if(fileExists(factionLogo) == true) {
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());
Texture2D *checkLogo = Renderer::preloadTexture(factionLogo);
if(checkLogo != NULL) {
const Metrics &metrics= Metrics::getInstance();
int minWidthDifference = abs(metrics.getScreenW() - checkLogo->getPixmapConst()->getW());
int minHeightDifference = abs(metrics.getScreenH() - checkLogo->getPixmapConst()->getH());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Logo info: %d x %d (%d,%d)\n",checkLogo->getPixmapConst()->getW(),checkLogo->getPixmapConst()->getH(),minWidthDifference,minHeightDifference);
if(minWidthDifference < bestMinWidthDiff) {
bestMinWidthDiff = minWidthDifference;
bestLogoIndex = logoIndex;
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 New best logo is [%s]\n",factionLogo.c_str());
}
else if(minWidthDifference == bestMinWidthDiff &&
minHeightDifference < bestMinHeightDiff) {
bestMinHeightDiff = minHeightDifference;
bestLogoIndex = logoIndex;
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 New best logo is [%s]\n",factionLogo.c_str());
}
}
}
}
}
string factionLogo = path + loadScreenList[bestLogoIndex];
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());
if(fileExists(factionLogo) == true) {
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());
result = factionLogo;
if(logger != NULL) {
logger->loadLoadingScreen(result);
}
loadingImageUsed = true;
break;
}
}
// Check if this is a linked faction
else {
//!!!
string factionXMLFile = path + factionName + ".xml";
//printf("A factionXMLFile [%s]\n",factionXMLFile.c_str());
if(fileExists(factionXMLFile) == true) {
XmlTree xmlTreeFaction(XML_RAPIDXML_ENGINE);
std::map<string,string> mapExtraTagReplacementValues;
xmlTreeFaction.load(factionXMLFile, Properties::getTagReplacementValues(&mapExtraTagReplacementValues),true,true);
const XmlNode *rootNode= xmlTreeFaction.getRootNode();
//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());
//printf("B factionXMLFile [%s] root name [%s]\n",factionXMLFile.c_str(),rootNode->getName().c_str());
if(rootNode->hasChild("link") == true) {
rootNode = rootNode->getChild("link");
}
if(rootNode->getName() == "link" && rootNode->hasChild("techtree") == true) {
const XmlNode *linkNode = rootNode;
//printf("C factionXMLFile [%s]\n",factionXMLFile.c_str());
//if(linkNode->hasChild("techtree") == true) {
const XmlNode *techtreeNode = linkNode->getChild("techtree");
string linkedTechTreeName = techtreeNode->getAttribute("name")->getValue();
//printf("D factionXMLFile [%s] linkedTechTreeName [%s]\n",factionXMLFile.c_str(),linkedTechTreeName.c_str());
if(linkedTechTreeName != "") {
string linkedTechTreePath=TechTree::findPath(linkedTechTreeName,pathList);
string techTreePath=linkedTechTreePath;
endPathWithSlash(techTreePath);
string linkedCurrentPath = techTreePath + "factions/" + factionName;
endPathWithSlash(linkedCurrentPath);
//string linkedTmppath= linkedCurrentPath + factionName +".xml";
path = linkedCurrentPath;
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());
//printf("D1 idx = %d\ncurrentPath [%s]\npath [%s]\npathList[idx] [%s]\n",idx,currentPath.c_str(),path.c_str(),pathList[idx].c_str());
if(isdir(path.c_str()) == true) {
endPathWithSlash(path);
//printf("E path [%s]\n",path.c_str());
loadScreenList.clear();
findAll(path + factionLogoFilter, loadScreenList, false, false);
if(loadScreenList.empty() == false) {
string factionLogo = path + loadScreenList[0];
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());
//printf("F factionLogo [%s]\n",factionLogo.c_str());
if(fileExists(factionLogo) == true) {
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());
result = factionLogo;
if(logger != NULL) {
logger->loadLoadingScreen(result);
}
loadingImageUsed = true;
break;
}
}
}
}
//}
}
}
}
}
if(loadingImageUsed == true) {
break;
}
}
}
//break;
//}
//}
return result;
}
string Game::extractTechLogoFile(string scenarioDir, string techName,
bool &loadingImageUsed, Logger *logger,string factionLogoFilter) {
string result = "";
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__);
Config &config = Config::getInstance();
vector<string> pathList = config.getPathListForType(ptTechs, scenarioDir);
for(int idx = 0; idx < (int)pathList.size(); idx++) {
string currentPath = pathList[idx];
endPathWithSlash(currentPath);
string path = currentPath + techName;
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());
if(isdir(path.c_str()) == true) {
endPathWithSlash(path);
vector<string> loadScreenList;
findAll(path + factionLogoFilter, loadScreenList, false, false);
if(loadScreenList.empty() == false) {
string factionLogo = path + loadScreenList[0];
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());
if(fileExists(factionLogo) == true) {
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());
result = factionLogo;
if(logger != NULL) {
logger->loadLoadingScreen(result);
}
loadingImageUsed = true;
break;
}
}
}
if(loadingImageUsed == true) {
break;
}
}
return result;
}
void Game::loadHudTexture(const GameSettings *settings)
{
string factionName = "";
string techName = settings->getTech();
string scenarioDir = extractDirectoryPathFromFile(settings->getScenarioDir());
//printf("In loadHudTexture, scenarioDir [%s]\n",scenarioDir.c_str());
for(int i=0; i < settings->getFactionCount(); ++i ) {
if((settings->getFactionControl(i) == ctHuman) || (settings->getFactionControl(i) == ctNetwork
&& settings->getThisFactionIndex() == i)){
factionName= settings->getFactionTypeName(i);
break;
}
}
if(factionName != "") {
bool hudFound = false;
Config &config= Config::getInstance();
vector<string> pathList= config.getPathListForType(ptTechs, scenarioDir);
for(int idx= 0; hudFound == false && idx < (int)pathList.size(); idx++){
string currentPath= pathList[idx];
endPathWithSlash(currentPath);
vector<string> hudList;
string path= currentPath + techName + "/" + "factions" + "/" + factionName;
endPathWithSlash(path);
findAll(path + GameConstants::HUD_SCREEN_FILE_FILTER, hudList, false, false);
if(hudList.empty() == false){
for(unsigned int hudIdx = 0; hudFound == false && hudIdx < (unsigned int)hudList.size(); ++hudIdx) {
string hudImageFileName= path + hudList[hudIdx];
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] looking for a HUD [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,hudImageFileName.c_str());
if(fileExists(hudImageFileName) == true){
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled)
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found HUD image [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,hudImageFileName.c_str());
Texture2D* texture= Renderer::findTexture(hudImageFileName);
gui.setHudTexture(texture);
hudFound = true;
//printf("Hud texture found! \n");
break;
}
}
}
}
}
}
string Game::findFactionLogoFile(const GameSettings *settings, Logger *logger,
string factionLogoFilter) {
string result = "";
if(settings == NULL) {
result = "";
}
else {
string mapName = settings->getMap();
string tilesetName = settings->getTileset();
string techName = settings->getTech();
string scenarioName = settings->getScenario();
bool loadingImageUsed = false;
if(logger != NULL) {
logger->setState(Lang::getInstance().getString("Loading"));
if(scenarioName.empty()) {
string scenarioDir = extractDirectoryPathFromFile(settings->getScenarioDir());
TechTree techTree(Config::getInstance().getPathListForType(ptTechs,scenarioDir));
logger->setSubtitle(formatString(mapName) + " - " +
formatString(tilesetName) + " - " + formatString(techTree.getTranslatedName(techName)));
}
else {
logger->setSubtitle(formatString(scenarioName));
}
}
string scenarioDir = "";
bool skipCustomLoadScreen = false;
if(skipCustomLoadScreen == false) {
scenarioDir = extractScenarioLogoFile(settings, result, loadingImageUsed,
logger, factionLogoFilter);
}
// try to use a faction related loading screen
if(skipCustomLoadScreen == false && loadingImageUsed == false) {
for(int i=0; i < settings->getFactionCount(); ++i ) {
if( settings->getFactionControl(i) == ctHuman ||
(settings->getFactionControl(i) == ctNetwork && settings->getThisFactionIndex() == i)) {
result = extractFactionLogoFile(loadingImageUsed, settings->getFactionTypeName(i),
scenarioDir, techName, logger, factionLogoFilter);
break;
}
}
}
// try to use a tech related loading screen
if(skipCustomLoadScreen == false && loadingImageUsed == false){
result = extractTechLogoFile(scenarioDir, techName,
loadingImageUsed, logger, factionLogoFilter);
}
}
return result;
}
vector<Texture2D *> Game::processTech(string techName) {
vector<Texture2D *> logoFiles;
bool enableFactionTexturePreview = Config::getInstance().getBool("FactionPreview","true");
if(enableFactionTexturePreview) {
//string currentTechName_factionPreview = techName;
vector<string> factions;
vector<string> techPaths = Config::getInstance().getPathListForType(ptTechs);
for(int idx = 0; idx < (int)techPaths.size(); idx++) {
string &techPath = techPaths[idx];
endPathWithSlash(techPath);
findAll(techPath + techName + "/factions/*.", factions, false, false);
if(factions.empty() == false) {
for(unsigned int factionIdx = 0; factionIdx < (unsigned int)factions.size(); ++factionIdx) {
bool loadingImageUsed = false;
string currentFactionName_factionPreview = factions[factionIdx];
string factionLogo = Game::extractFactionLogoFile(
loadingImageUsed,
currentFactionName_factionPreview,
"",
techName,
NULL,
GameConstants::PREVIEW_SCREEN_FILE_FILTER);
if(factionLogo == "") {
factionLogo = Game::extractFactionLogoFile(
loadingImageUsed,
currentFactionName_factionPreview,
"",
techName,
NULL,
GameConstants::LOADING_SCREEN_FILE_FILTER);
}
if(factionLogo != "") {
Texture2D *texture = Renderer::preloadTexture(factionLogo);
logoFiles.push_back(texture);
}
}
}
}
}
return logoFiles;
}
void Game::load() {
load(lgt_All);
}
void Game::load(int loadTypes) {
bool showPerfStats = Config::getInstance().getBool("ShowPerfStats","false");
Chrono chronoPerf;
if(showPerfStats) chronoPerf.start();
char perfBuf[8096]="";
std::vector<string> perfList;
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
FileCRCPreCacheThread * &preCacheCRCThreadPtr = CacheManager::getCachedItem< FileCRCPreCacheThread * >(GameConstants::preCacheThreadCacheLookupKey);
if(preCacheCRCThreadPtr != NULL) {
preCacheCRCThreadPtr->setPauseForGame(true);
}
std::map<string,vector<pair<string, string> > > loadedFileList;
originalDisplayMsgCallback = NetworkInterface::getDisplayMessageFunction();
NetworkInterface::setDisplayMessageFunction(ErrorDisplayMessage);
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());
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
soundRenderer.stopAllSounds(fadeMusicMilliseconds);
BaseColorPickEntity::resetUniqueColors();
Config &config = Config::getInstance();
Logger &logger= Logger::getInstance();
string mapName= gameSettings.getMap();
string tilesetName= gameSettings.getTileset();
string techName= gameSettings.getTech();
string scenarioName= gameSettings.getScenario();
string data_path= getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
// loadHints
if(data_path != ""){
endPathWithSlash(data_path);
}
string user_data_path = config.getString("UserData_Root","");
if(user_data_path != "") {
endPathWithSlash(user_data_path);
}
string englishFile=getGameCustomCoreDataPath(data_path, "data/lang/hint/hint_"+Lang::getInstance().getDefaultLanguage()+".lng");
string languageFile=getGameCustomCoreDataPath(data_path, "data/lang/hint/hint_"+ Lang::getInstance().getLanguage() +".lng");
string languageFileUserData=user_data_path + "data/lang/hint/hint_"+ Lang::getInstance().getLanguage() +".lng";
if(fileExists(languageFileUserData) == true){
languageFile=languageFileUserData;
}
if(fileExists(languageFile) == false){
// if there is no language specific file use english instead
languageFile=englishFile;
}
if(fileExists(englishFile) == false){
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] file [%s] not found\n",__FILE__,__FUNCTION__,__LINE__,englishFile.c_str());
}
else {
logger.loadGameHints(englishFile,languageFile,true);
::Shared::Platform::Window::handleEvent();
SDL_PumpEvents();
}
if((loadTypes & lgt_FactionPreview) == lgt_FactionPreview) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
Game::findFactionLogoFile(&gameSettings, &logger);
::Shared::Platform::Window::handleEvent();
SDL_PumpEvents();
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
loadHudTexture(&gameSettings);
const string markCellTextureFilename = data_path + "data/core/misc_textures/mark_cell.png";
markCellTexture = Renderer::findTexture(markCellTextureFilename);
const string unmarkCellTextureFilename = data_path + "data/core/misc_textures/unmark_cell.png";
unmarkCellTexture = Renderer::findTexture(unmarkCellTextureFilename);
const string highlightCellTextureFilename = data_path + "data/core/misc_textures/pointer.png";
highlightCellTexture = Renderer::findTexture(highlightCellTextureFilename);
string scenarioDir = "";
if(gameSettings.getScenarioDir() != "") {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
scenarioDir = gameSettings.getScenarioDir();
if(EndsWith(scenarioDir, ".xml") == true) {
scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4);
scenarioDir = scenarioDir.erase(scenarioDir.size() - gameSettings.getScenario().size(), gameSettings.getScenario().size() + 1);
}
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//tileset
if((loadTypes & lgt_TileSet) == lgt_TileSet) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
world.loadTileset( config.getPathListForType(ptTilesets,scenarioDir),
tilesetName, &checksum, loadedFileList);
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
// give CPU time to update other things to avoid apperance of hanging
sleep(0);
::Shared::Platform::Window::handleEvent();
SDL_PumpEvents();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
set<string> factions;
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
for ( int i=0; i < gameSettings.getFactionCount(); ++i ) {
factions.insert(gameSettings.getFactionTypeName(i));
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
if((loadTypes & lgt_TechTree) == lgt_TechTree) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//tech, load before map because of resources
world.loadTech( config.getPathListForType(ptTechs,scenarioDir), techName,
factions, &checksum,loadedFileList);
if(world.getTechTree() == NULL || world.getTechTree()->getNameUntranslated() == "") {
char szBuf[8096]="";
snprintf(szBuf,8096,"Line ref: %d, ERROR: Cannot find techtree: [%s]",__LINE__,techName.c_str());
throw megaglest_runtime_error(szBuf, true);
}
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
// give CPU time to update other things to avoid apperance of hanging
sleep(0);
::Shared::Platform::Window::handleEvent();
SDL_PumpEvents();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//map
if((loadTypes & lgt_Map) == lgt_Map) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
world.loadMap(Config::getMapPath(mapName,scenarioDir), &checksum);
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
// give CPU time to update other things to avoid apperance of hanging
sleep(0);
::Shared::Platform::Window::handleEvent();
SDL_PumpEvents();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//scenario
if((loadTypes & lgt_Scenario) == lgt_Scenario) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(scenarioName.empty() == false) {
bool isTutorial = Scenario::isGameTutorial(gameSettings.getScenarioDir());
//printf("Loading scenario gameSettings.getScenarioDir() [%s] scenarioName [%s] isTutorial: %d\n",gameSettings.getScenarioDir().c_str(),scenarioName.c_str(),isTutorial);
Lang::getInstance().loadScenarioStrings(gameSettings.getScenarioDir(), scenarioName, isTutorial);
//printf("In [%s::%s Line: %d] rootNode [%p][%s]\n",__FILE__,__FUNCTION__,__LINE__,loadGameNode,(loadGameNode != NULL ? loadGameNode->getName().c_str() : "none"));
world.loadScenario(gameSettings.getScenarioDir(), &checksum, false,loadGameNode);
}
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
// give CPU time to update other things to avoid apperance of hanging
sleep(0);
SDL_PumpEvents();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(showPerfStats && chronoPerf.getMillis() >= 50) {
for(unsigned int x = 0; x < perfList.size(); ++x) {
printf("%s",perfList[x].c_str());
}
}
}
void Game::init() {
init(false);
}
void Game::init(bool initForPreviewOnly) {
bool showPerfStats = Config::getInstance().getBool("ShowPerfStats","false");
Chrono chronoPerf;
if(showPerfStats) chronoPerf.start();
char perfBuf[8096]="";
std::vector<string> perfList;
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
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);
Lang &lang= Lang::getInstance();
Logger &logger= Logger::getInstance();
CoreData &coreData= CoreData::getInstance();
Renderer &renderer= Renderer::getInstance();
Map *map= world.getMap();
NetworkManager &networkManager= NetworkManager::getInstance();
GameSettings::playerDisconnectedText = "*" + lang.getString("AI") + "* ";
if(map == NULL) {
throw megaglest_runtime_error("map == NULL");
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(initForPreviewOnly == false) {
logger.setState(lang.getString("Initializing"));
//message box
mainMessageBox.init(lang.getString("Yes"), lang.getString("No"));
mainMessageBox.setEnabled(false);
//message box
errorMessageBox.init(lang.getString("Ok"));
errorMessageBox.setEnabled(false);
errorMessageBox.setY(20);
//init world, and place camera
commander.init(&world);
// give CPU time to update other things to avoid apperance of hanging
sleep(0);
::Shared::Platform::Window::handleEvent();
SDL_PumpEvents();
}
try {
world.init(this, gameSettings.getDefaultUnits());
}
catch(const megaglest_runtime_error &ex) {
string sErrBuf = "";
if(ex.wantStackTrace() == true) {
char szErrBuf[8096]="";
snprintf(szErrBuf,8096,"In [%s::%s %d]",__FILE__,__FUNCTION__,__LINE__);
sErrBuf = string(szErrBuf) + string("\nerror [") + string(ex.what()) + string("]\n");
}
else {
sErrBuf = ex.what();
}
SystemFlags::OutputDebug(SystemFlags::debugError,sErrBuf.c_str());
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,sErrBuf.c_str());
if(errorMessageBox.getEnabled() == false) {
ErrorDisplayMessage(ex.what(),true);
}
}
catch(const exception &ex) {
char szErrBuf[8096]="";
snprintf(szErrBuf,8096,"In [%s::%s %d]",__FILE__,__FUNCTION__,__LINE__);
string sErrBuf = string(szErrBuf) + string("\nerror [") + string(ex.what()) + string("]\n");
SystemFlags::OutputDebug(SystemFlags::debugError,sErrBuf.c_str());
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,sErrBuf.c_str());
if(errorMessageBox.getEnabled() == false) {
ErrorDisplayMessage(ex.what(),true);
}
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
if(loadGameNode != NULL) {
//world.getMapPtr()->loadGame(loadGameNode,&world);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(initForPreviewOnly == false) {
// give CPU time to update other things to avoid apperance of hanging
sleep(0);
::Shared::Platform::Window::handleEvent();
SDL_PumpEvents();
gui.init(this);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// give CPU time to update other things to avoid apperance of hanging
sleep(0);
//SDL_PumpEvents();
chatManager.init(&console, world.getThisTeamIndex());
console.clearStoredLines();
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
if(this->loadGameNode == NULL) {
gameCamera.init(map->getW(), map->getH());
// camera default height calculation
if(map->getCameraHeight()>0 && gameCamera.getCalculatedDefault()<map->getCameraHeight()){
gameCamera.setCalculatedDefault(map->getCameraHeight());
}
else if(gameCamera.getCalculatedDefault()<map->getMaxMapHeight()+13.0f){
gameCamera.setCalculatedDefault(map->getMaxMapHeight()+13.0f);
}
if(world.getThisFaction() != NULL) {
const Vec2i &v= map->getStartLocation(world.getThisFaction()->getStartLocationIndex());
gameCamera.setPos(Vec2f(v.x, v.y));
}
}
else {
gui.loadGame(loadGameNode,&world);
if(inJoinGameLoading == true) {
gameCamera.init(map->getW(), map->getH());
// camera default height calculation
if(map->getCameraHeight()>0 && gameCamera.getCalculatedDefault()<map->getCameraHeight()){
gameCamera.setCalculatedDefault(map->getCameraHeight());
}
else if(gameCamera.getCalculatedDefault()<map->getMaxMapHeight()+13.0f){
gameCamera.setCalculatedDefault(map->getMaxMapHeight()+13.0f);
}
if(world.getThisFaction() != NULL) {
const Vec2i &v= map->getStartLocation(world.getThisFaction()->getStartLocationIndex());
gameCamera.setPos(Vec2f(v.x, v.y));
}
}
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
NetworkRole role = nrIdle;
if(initForPreviewOnly == false) {
// give CPU time to update other things to avoid apperance of hanging
sleep(0);
::Shared::Platform::Window::handleEvent();
SDL_PumpEvents();
scriptManager.init(&world, &gameCamera,loadGameNode);
//good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
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__);
//create AIs
bool enableServerControlledAI = this->gameSettings.getEnableServerControlledAI();
bool isNetworkGame = this->gameSettings.isNetworkGame();
role = networkManager.getNetworkRole();
masterController.clearSlaves(true);
deleteValues(aiInterfaces.begin(), aiInterfaces.end());
std::vector<SlaveThreadControllerInterface *> slaveThreadList;
aiInterfaces.resize(world.getFactionCount());
for(int i=0; i < world.getFactionCount(); ++i) {
Faction *faction= world.getFaction(i);
//printf("Controltype = %d for index = %d\n",faction->getControlType(),i);
if(faction->getCpuControl(enableServerControlledAI,isNetworkGame,role) == true) {
//printf("** Loading AI player for Controltype = %d for index = %d\n",faction->getControlType(),i);
aiInterfaces[i]= new AiInterface(*this, i, faction->getTeam());
if(loadGameNode != NULL) {
aiInterfaces[i]->loadGame(loadGameNode,faction);
}
char szBuf[8096]="";
snprintf(szBuf,8096,Lang::getInstance().getString("LogScreenGameLoadingCreatingAIFaction","",true).c_str(),i);
logger.add(szBuf, true);
slaveThreadList.push_back(aiInterfaces[i]->getWorkerThread());
}
else {
aiInterfaces[i]= NULL;
}
}
if(Config::getInstance().getBool("EnableNewThreadManager","false") == true) {
masterController.setSlaves(slaveThreadList);
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// give CPU time to update other things to avoid apperance of hanging
sleep(0);
::Shared::Platform::Window::handleEvent();
SDL_PumpEvents();
if(world.getFactionCount() == 1 && world.getFaction(0)->getPersonalityType() == fpt_Observer) {
withRainEffect = false;
}
if(withRainEffect) {
//weather particle systems
if(world.getTileset()->getWeather() == wRainy) {
logger.add(Lang::getInstance().getString("LogScreenGameLoadingCreatingRainParticles","",true), true);
weatherParticleSystem= new RainParticleSystem();
weatherParticleSystem->setSpeed(12.f / GameConstants::updateFps);
weatherParticleSystem->setPos(gameCamera.getPos());
renderer.manageParticleSystem(weatherParticleSystem, rsGame);
}
else if(world.getTileset()->getWeather() == wSnowy) {
logger.add(Lang::getInstance().getString("LogScreenGameLoadingCreatingSnowParticles","",true), true);
weatherParticleSystem= new SnowParticleSystem(1200);
weatherParticleSystem->setSpeed(1.5f / GameConstants::updateFps);
weatherParticleSystem->setPos(gameCamera.getPos());
weatherParticleSystem->setTexture(coreData.getSnowTexture());
renderer.manageParticleSystem(weatherParticleSystem, rsGame);
}
}
else if(world.getTileset()->getWeather() == wRainy) {
world.getTileset()->setWeather(wSunny);
}
renderer.manageDeferredParticleSystems();
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
//init renderer state
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Initializing renderer\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__);
logger.add(Lang::getInstance().getString("LogScreenGameLoadingInitRenderer","",true), true);
//printf("Before renderer.initGame\n");
renderer.initGame(this,this->getGameCameraPtr());
//printf("After renderer.initGame\n");
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
for(int i=0; i < world.getFactionCount(); ++i) {
Faction *faction= world.getFaction(i);
if(faction != NULL) {
faction->deletePixels();
}
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
if(initForPreviewOnly == false) {
//good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// give CPU time to update other things to avoid apperance of hanging
sleep(0);
::Shared::Platform::Window::handleEvent();
SDL_PumpEvents();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Waiting for network\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__);
logger.add(Lang::getInstance().getString("LogScreenGameLoadingWaitForNetworkPlayers","",true), true);
networkManager.getGameNetworkInterface()->waitUntilReady(&checksum);
//std::string worldLog = world.DumpWorldToLog(true);
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__);
logger.add(Lang::getInstance().getString("LogScreenGameLoadingStartingMusic","",true), true);
if(this->masterserverMode == false) {
if(world.getThisFaction() == NULL) {
throw megaglest_runtime_error("world.getThisFaction() == NULL");
}
if(world.getThisFaction()->getType() == NULL) {
throw megaglest_runtime_error("world.getThisFaction()->getType() == NULL");
}
//if(world.getThisFaction()->getType()->getMusic() == NULL) {
// throw megaglest_runtime_error("world.getThisFaction()->getType()->getMusic() == NULL");
//}
}
//sounds
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
soundRenderer.stopAllSounds(fadeMusicMilliseconds);
soundRenderer= SoundRenderer::getInstance();
Tileset *tileset= world.getTileset();
AmbientSounds *ambientSounds= tileset->getAmbientSounds();
//rain
if(tileset->getWeather() == wRainy && ambientSounds->isEnabledRain()) {
logger.add(Lang::getInstance().getString("LogScreenGameLoadingStartingAmbient","",true), true);
currentAmbientSound = ambientSounds->getRain();
//printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
soundRenderer.playAmbient(currentAmbientSound);
}
//snow
if(tileset->getWeather() == wSnowy && ambientSounds->isEnabledSnow()) {
logger.add(Lang::getInstance().getString("LogScreenGameLoadingStartingAmbient","",true), true);
currentAmbientSound = ambientSounds->getSnow();
//printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
soundRenderer.playAmbient(currentAmbientSound);
}
if(this->masterserverMode == false) {
StrSound *gameMusic= world.getThisFaction()->getType()->getMusic();
soundRenderer.playMusic(gameMusic);
}
logger.add(Lang::getInstance().getString("LogScreenGameLoadingLaunchGame","",true));
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
//throw "test";
logger.setCancelLoadingEnabled(false);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"================ STARTING GAME ================\n");
if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled) SystemFlags::OutputDebug(SystemFlags::debugPathFinder,"================ STARTING GAME ================\n");
setupPopupMenus(false);
for(int i=0; i < world.getFactionCount(); ++i) {
Faction *faction= world.getFaction(i);
//printf("Check for team switch to observer i = %d, team = %d [%d]\n",i,faction->getTeam(),(GameConstants::maxPlayers -1 + fpt_Observer));
if(faction != NULL && faction->getTeam() == GameConstants::maxPlayers -1 + fpt_Observer) {
faction->setPersonalityType(fpt_Observer);
world.getStats()->setPersonalityType(i, faction->getPersonalityType());
}
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
if(role == nrClient) {
ClientInterface *clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
if(clientInterface != NULL && clientInterface->getResumeInGameJoin() == true) {
//printf("Client sending resume message to server...\n");
clientInterface->sendResumeGameMessage();
//this->initialResumeSpeedLoops = true;
}
}
printf("Game unique identifier is: %s\n",this->gameSettings.getGameUUID().c_str());
gameStarted = true;
if(this->masterserverMode == true) {
world.getStats()->setIsMasterserverMode(true);
printf("New game has started...\n");
}
if(isFlagType1BitEnabled(ft1_network_synch_checks_verbose) == true) {
printf("*Note: Monitoring Network CRC VERBOSE synchronization...\n");
}
else if(isFlagType1BitEnabled(ft1_network_synch_checks) == true) {
printf("*Note: Monitoring Network CRC NORMAL synchronization...\n");
}
//NetworkRole role = networkManager.getNetworkRole();
if(role == nrServer) {
networkManager.initServerInterfaces(this);
}
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"=============================================\n");
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"==== START GAME ====\n");
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"=============================================\n");
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"Starting framecount: %d\n",world.getFrameCount());
if(showPerfStats && chronoPerf.getMillis() >= 50) {
for(unsigned int x = 0; x < perfList.size(); ++x) {
printf("%s",perfList[x].c_str());
}
}
}
// ==================== update ====================
void Game::reInitGUI() {
gui.init(this);
}
void Game::setupPopupMenus(bool checkClientAdminOverrideOnly) {
Lang &lang= Lang::getInstance();
NetworkManager &networkManager= NetworkManager::getInstance();
NetworkRole role = networkManager.getNetworkRole();
ClientInterface *clientInterface = NULL;
ServerInterface *serverInterface = NULL;
bool allowAdminMenuItems = false;
bool forceJoinInProgressUpdate = false;
if(role == nrServer) {
allowAdminMenuItems = true;
if(disconnectPlayerPopupMenuIndex == -1) {
serverInterface = dynamic_cast<ServerInterface *>(networkManager.getServerInterface());
if(serverInterface != NULL && checkClientAdminOverrideOnly == true) {
for(int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
MutexSafeWrapper safeMutex(serverInterface->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
ConnectionSlot *slot = serverInterface->getSlot(faction->getStartLocationIndex(),false);
if(slot != NULL && slot->getConnectHasHandshaked() == true &&
slot->getCurrentFrameCount() <= 0) {
//printf("Connected slot can be disconnected: %d\n",slot->getPlayerIndex());
forceJoinInProgressUpdate = true;
break;
}
}
}
}
}
else if(role == nrClient) {
clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
if(clientInterface != NULL &&
(gameSettings.getMasterserver_admin() == clientInterface->getSessionKey() ||
clientInterface->isMasterServerAdminOverride() == true)) {
allowAdminMenuItems = true;
}
}
if(checkClientAdminOverrideOnly == false ||
forceJoinInProgressUpdate == true ||
(clientInterface != NULL &&
(gameSettings.getMasterserver_admin() != clientInterface->getSessionKey() &&
clientInterface->isMasterServerAdminOverride() == true))) {
exitGamePopupMenuIndex = -1;
joinTeamPopupMenuIndex = -1;
pauseGamePopupMenuIndex = -1;
saveGamePopupMenuIndex = -1;
loadGamePopupMenuIndex = -1;
keyboardSetupPopupMenuIndex = -1;
disconnectPlayerPopupMenuIndex = -1;
if(checkClientAdminOverrideOnly == true && clientInterface != NULL) {
gameSettings.setMasterserver_admin(clientInterface->getSessionKey());
gameSettings.setMasterserver_admin_faction_index(clientInterface->getPlayerIndex());
}
//PopupMenu popupMenu;
std::vector<string> menuItems;
menuItems.push_back(lang.getString("ExitGameMenu?"));
exitGamePopupMenuIndex = (int)menuItems.size()-1;
if((gameSettings.getFlagTypes1() & ft1_allow_team_switching) == ft1_allow_team_switching &&
world.getThisFaction() != NULL && world.getThisFaction()->getPersonalityType() != fpt_Observer) {
menuItems.push_back(lang.getString("JoinOtherTeam"));
joinTeamPopupMenuIndex = (int)menuItems.size()-1;
}
if(allowAdminMenuItems == true){
menuItems.push_back(lang.getString("PauseResumeGame"));
pauseGamePopupMenuIndex= (int)menuItems.size() - 1;
if(gameSettings.isNetworkGame() == false || gameSettings.getScenario() != "") {
menuItems.push_back(lang.getString("SaveGame"));
saveGamePopupMenuIndex= (int)menuItems.size() - 1;
}
if(gameSettings.isNetworkGame() == true) {
menuItems.push_back(lang.getString("DisconnectNetorkPlayer"));
disconnectPlayerPopupMenuIndex= (int)menuItems.size() - 1;
}
}
menuItems.push_back(lang.getString("Keyboardsetup"));
keyboardSetupPopupMenuIndex = (int)menuItems.size()-1;
menuItems.push_back(lang.getString("Cancel"));
popupMenu.setW(100);
popupMenu.setH(100);
popupMenu.init(lang.getString("GameMenuTitle"),menuItems);
popupMenu.setEnabled(false);
popupMenu.setVisible(false);
popupMenuSwitchTeams.setEnabled(false);
popupMenuSwitchTeams.setVisible(false);
popupMenuDisconnectPlayer.setEnabled(false);
popupMenuDisconnectPlayer.setVisible(false);
}
}
void Game::processNetworkSynchChecksIfRequired() {
bool isNetworkGame = this->gameSettings.isNetworkGame();
if (isNetworkGame == true && NetworkManager::getInstance().getGameNetworkInterface() != NULL) {
GameSettings *settings = world.getGameSettingsPtr();
if(settings != NULL) {
bool calculateNetworkCRC = false;
if(isFlagType1BitEnabled(ft1_network_synch_checks) == true ||
isFlagType1BitEnabled(ft1_network_synch_checks_verbose) == true) {
calculateNetworkCRC = true;
}
if(calculateNetworkCRC == true) {
NetworkManager &networkManager = NetworkManager::getInstance();
NetworkRole role = networkManager.getNetworkRole();
NetworkInterface *netIntf = networkManager.getGameNetworkInterface();
for(int index = 0; index < GameConstants::maxPlayers; ++index) {
if(index < world.getFactionCount()) {
Faction *faction = world.getFaction(index);
netIntf->setNetworkPlayerFactionCRC(index,faction->getCRC().getSum());
if(settings != NULL) {
if(isFlagType1BitEnabled(ft1_network_synch_checks_verbose) == true) {
faction->addCRC_DetailsForWorldFrame(world.getFrameCount(),role == nrServer);
}
else if(isFlagType1BitEnabled(ft1_network_synch_checks) == true &&
world.getFrameCount() % 20 == 0) {
faction->addCRC_DetailsForWorldFrame(world.getFrameCount(),role == nrServer);
}
}
}
else {
netIntf->setNetworkPlayerFactionCRC(index,0);
}
}
}
}
}
}
//update
void Game::update() {
try {
if(currentUIState != NULL) {
currentUIState->update();
}
bool showPerfStats = Config::getInstance().getBool("ShowPerfStats","false");
Chrono chronoPerf;
char perfBuf[8096]="";
std::vector<string> perfList;
if(showPerfStats) chronoPerf.start();
if(showPerfStats) {
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());
perfList.push_back(perfBuf);
}
Chrono chronoGamePerformanceCounts;
Chrono chrono;
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
// a) Updates non dependent on speed
// set game stats for host
NetworkManager &networkManager = NetworkManager::getInstance();
NetworkRole role = networkManager.getNetworkRole();
if(role == nrServer) {
ServerInterface *server = NetworkManager::getInstance().getServerInterface(false);
if(server != NULL) {
server->setGameStats(world.getStats());
}
}
bool pendingQuitError = (quitPendingIndicator == true ||
(NetworkManager::getInstance().getGameNetworkInterface() != NULL &&
NetworkManager::getInstance().getGameNetworkInterface()->getQuit()));
if(pendingQuitError == true &&
(this->masterserverMode == true ||
(mainMessageBox.getEnabled() == false && errorMessageBox.getEnabled() == false))) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
quitTriggeredIndicator = true;
return;
}
if(this->masterserverMode == false) {
if(world.getFactionCount() > 0 && world.getThisFaction()->getFirstSwitchTeamVote() != NULL) {
const SwitchTeamVote *vote = world.getThisFaction()->getFirstSwitchTeamVote();
GameSettings *settings = world.getGameSettingsPtr();
Lang &lang= Lang::getInstance();
char szBuf[8096]="";
if(lang.hasString("AllowPlayerJoinTeam") == true) {
snprintf(szBuf,8096,lang.getString("AllowPlayerJoinTeam").c_str(),settings->getNetworkPlayerName(vote->factionIndex).c_str(),vote->oldTeam,vote->newTeam);
}
else {
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);
}
switchTeamConfirmMessageBox.setText(szBuf);
switchTeamConfirmMessageBox.init(lang.getString("Yes"), lang.getString("No"));
switchTeamConfirmMessageBox.setEnabled(true);
world.getThisFactionPtr()->setCurrentSwitchTeamVoteFactionIndex(vote->factionIndex);
}
}
//misc
updateFps++;
mouse2d= (mouse2d+1) % Renderer::maxMouse2dAnim;
//console
console.update();
// b) Updates depandant on speed
int updateLoops= getUpdateLoops();
// Temp speed boost when player first joins an in progress game
if(this->initialResumeSpeedLoops == true) {
printf("Resume In Progress Game: %d\n",__LINE__);
this->initialResumeSpeedLoops = false;
//updateLoops = 80;
}
chronoGamePerformanceCounts.start();
bool enableServerControlledAI = this->gameSettings.getEnableServerControlledAI();
if(role == nrClient && updateLoops == 1 && world.getFrameCount() >= (gameSettings.getNetworkFramePeriod() * 2) ) {
ClientInterface *clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
if(clientInterface != NULL) {
uint64 lastNetworkFrameFromServer = clientInterface->getCachedLastPendingFrameCount();
/////////////////////////////////
// TTTT new attempt to make things smoother:
///////////////
////////////////////////////////////////////
//get stats of received/waiting for packages
////////////////////////////////////////////
// calculate current receive Index slot:
int index = ((world.getFrameCount()
- (world.getFrameCount()
% gameSettings.getNetworkFramePeriod()))
/ gameSettings.getNetworkFramePeriod())
% GameConstants::networkSmoothInterval;
// clean the next frame slot
receivedTooEarlyInFrames[(index+1)%GameConstants::networkSmoothInterval]=-1;
framesNeededToWaitForServerMessage[(index+1)%GameConstants::networkSmoothInterval]=-1;
if(receivedTooEarlyInFrames[index]==-1){
// we need to check if we already received something for next frame
if(lastNetworkFrameFromServer > 0 && lastNetworkFrameFromServer > (uint64)world.getFrameCount()) {
receivedTooEarlyInFrames[index]= lastNetworkFrameFromServer-world.getFrameCount();
}
}
if(framesNeededToWaitForServerMessage[index]==-1){
// calc time waiting for message in milliseconds to frames
int64 timeClientWaitedForLastMessage=clientInterface->getTimeClientWaitedForLastMessage();
if(timeClientWaitedForLastMessage>0){
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("world.getFrameCount():%d index %d Client waited:%d ms\n",world.getFrameCount(),index,(int)timeClientWaitedForLastMessage);
framesNeededToWaitForServerMessage[index]=timeClientWaitedForLastMessage*GameConstants::updateFps/1000;
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("ClienttimeClientWaitedForLastMessage:%d ms which is %d frames \n",(int)timeClientWaitedForLastMessage,framesNeededToWaitForServerMessage[index]);
}
else {
framesNeededToWaitForServerMessage[index]=0;
}
}
////////////////////////////////////////////
//use the recorded stats of received/waiting for packages
////////////////////////////////////////////
//lets see if the client is in front and had to wait for messages ...
//lets see if all last recorded frames where received too early
int minimum=0;
int allowedMaxFallback=5;
int countOfMessagesReceivedTooEarly=0;
int countOfMessagesReceivedTooLate=0;
int sumOfTooLateFrames=0;
bool cleanupStats=false;
for( int i=0;i<GameConstants::networkSmoothInterval;i++){
if(receivedTooEarlyInFrames[i]>allowedMaxFallback){
countOfMessagesReceivedTooEarly++;
if ( minimum == 0 || minimum > receivedTooEarlyInFrames[i] ){
minimum=receivedTooEarlyInFrames[i];
}
}
if(framesNeededToWaitForServerMessage[i]>0){
countOfMessagesReceivedTooLate++;
sumOfTooLateFrames+=framesNeededToWaitForServerMessage[i];
}
}
if( countOfMessagesReceivedTooEarly==GameConstants::networkSmoothInterval-1 ) // -1 because slot for next frame is already initialized
{// all packages where too early
// we catch up the minimum-catchupInterval of what we recorded
framesToCatchUpAsClient=minimum-allowedMaxFallback;
framesToSlowDownAsClient=0;
cleanupStats=true;
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Worldframe %d : Client will speed up: %d frames\n",world.getFrameCount(),framesToCatchUpAsClient);
}
else if(countOfMessagesReceivedTooLate>3){
framesToSlowDownAsClient=sumOfTooLateFrames/countOfMessagesReceivedTooLate;
framesToCatchUpAsClient=0;
cleanupStats=true;
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Worldframe %d : Client will slow down: %d frames\n",world.getFrameCount(),framesToSlowDownAsClient);
}
if(cleanupStats==true) {
// Once we decided to use the stats to do some correction, we reset/cleanup our recorded stats
for( int i=0;i<GameConstants::networkSmoothInterval;i++){
receivedTooEarlyInFrames[i]=-1;
framesNeededToWaitForServerMessage[i]=-1;
}
}
}
}
// if game is paused don't try to catch up
if(updateLoops > 0) {
// we catch up a bit smoother with updateLoops = 2
if(framesToCatchUpAsClient>0)
{
updateLoops = 2;
framesToCatchUpAsClient=framesToCatchUpAsClient-1;
}
if(framesToSlowDownAsClient>0)
{// slowdown still the hard way.
updateLoops = 0;
framesToSlowDownAsClient=framesToSlowDownAsClient-1;
}
}
addPerformanceCount("CalculateNetworkUpdateLoops",chronoGamePerformanceCounts.getMillis());
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());
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
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());
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
// Check to see if we are playing a network game and if any players
// have disconnected?
bool isNetworkGame = this->gameSettings.isNetworkGame();
chronoGamePerformanceCounts.start();
ReplaceDisconnectedNetworkPlayersWithAI(isNetworkGame, role);
addPerformanceCount("ReplaceDisconnectedNetworkPlayersWithAI",chronoGamePerformanceCounts.getMillis());
setupPopupMenus(true);
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());
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
if(updateLoops > 0) {
// update the frame based timer in the stats with at least one step
world.getStats()->addFramesToCalculatePlaytime();
//update
Chrono chronoReplay;
int64 lastReplaySecond = -1;
int replayCommandsPlayed = 0;
int replayTotal = commander.getReplayCommandListForFrameCount();
if(replayTotal > 0) {
chronoReplay.start();
}
do {
if(replayTotal > 0) {
replayCommandsPlayed = (replayTotal - commander.getReplayCommandListForFrameCount());
}
for(int i = 0; i < updateLoops; ++i) {
//if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
//AiInterface
if(commander.hasReplayCommandListForFrame() == false) {
chronoGamePerformanceCounts.start();
processNetworkSynchChecksIfRequired();
addPerformanceCount("CalculateNetworkCRCSynchChecks",chronoGamePerformanceCounts.getMillis());
const bool newThreadManager = Config::getInstance().getBool("EnableNewThreadManager","false");
if(newThreadManager == true) {
int currentFrameCount = world.getFrameCount();
masterController.signalSlaves(&currentFrameCount);
//bool slavesCompleted = masterController.waitTillSlavesTrigger(20000);
masterController.waitTillSlavesTrigger(20000);
}
else {
// Signal the faction threads to do any pre-processing
chronoGamePerformanceCounts.start();
bool hasAIPlayer = false;
for(int j = 0; j < world.getFactionCount(); ++j) {
Faction *faction = world.getFaction(j);
//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());
if( faction->getCpuControl(enableServerControlledAI,isNetworkGame,role) == true &&
scriptManager.getPlayerModifiers(j)->getAiEnabled() == true) {
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());
aiInterfaces[j]->signalWorkerThread(world.getFrameCount());
hasAIPlayer = true;
}
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
if(hasAIPlayer == true) {
//sleep(0);
Chrono chronoAI;
chronoAI.start();
const int MAX_FACTION_THREAD_WAIT_MILLISECONDS = 20000;
for(;chronoAI.getMillis() < MAX_FACTION_THREAD_WAIT_MILLISECONDS;) {
bool workThreadsFinished = true;
for(int j = 0; j < world.getFactionCount(); ++j) {
Faction *faction = world.getFaction(j);
if(faction == NULL) {
throw megaglest_runtime_error("faction == NULL");
}
if( faction->getCpuControl(enableServerControlledAI,isNetworkGame,role) == true &&
scriptManager.getPlayerModifiers(j)->getAiEnabled() == true) {
if(aiInterfaces[j]->isWorkerThreadSignalCompleted(world.getFrameCount()) == false) {
workThreadsFinished = false;
break;
}
}
}
if(workThreadsFinished == false) {
//sleep(0);
}
else {
break;
}
}
}
addPerformanceCount("ProcessAIWorkerThreads",chronoGamePerformanceCounts.getMillis());
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
}
else {
// Simply show a progress message while replaying commands
if(lastReplaySecond < chronoReplay.getSeconds()) {
lastReplaySecond = chronoReplay.getSeconds();
Renderer &renderer= Renderer::getInstance();
renderer.clearBuffers();
renderer.clearZBuffer();
renderer.reset2d();
char szBuf[8096]="";
snprintf(szBuf,8096,"Please wait, loading game with replay [%d / %d]...",replayCommandsPlayed,replayTotal);
string text = szBuf;
if(Renderer::renderText3DEnabled) {
Font3D *font = CoreData::getInstance().getMenuFontBig3D();
const Metrics &metrics= Metrics::getInstance();
int w= metrics.getVirtualW();
int renderX = (w / 2) - (font->getMetrics()->getTextWidth(text) / 2);
int h= metrics.getVirtualH();
int renderY = (h / 2) + (font->getMetrics()->getHeight(text) / 2);
renderer.renderText3D(
text, font,
Vec3f(1.f, 1.f, 0.f),
renderX, renderY, false);
}
else {
Font2D *font = CoreData::getInstance().getMenuFontBig();
const Metrics &metrics= Metrics::getInstance();
int w= metrics.getVirtualW();
int renderX = (w / 2);
int h= metrics.getVirtualH();
int renderY = (h / 2);
renderer.renderText(
text, font,
Vec3f(1.f, 1.f, 0.f),
renderX, renderY, true);
}
renderer.swapBuffers();
}
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
//World
chronoGamePerformanceCounts.start();
if(pendingQuitError == false) world.update();
addPerformanceCount("ProcessWorldUpdate",chronoGamePerformanceCounts.getMillis());
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);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
if(currentCameraFollowUnit != NULL) {
Vec3f c=currentCameraFollowUnit->getCurrMidHeightVector();
int rotation=currentCameraFollowUnit->getRotation();
float angle=rotation+180;
c.z=c.z+4*std::cos(degToRad(angle));
c.x=c.x+4*std::sin(degToRad(angle));
c.y=c.y+currentCameraFollowUnit->getType()->getHeight()/2.f+2.0f;
getGameCameraPtr()->setPos(c);
rotation=(540-rotation)%360;
getGameCameraPtr()->rotateToVH(18.0f,rotation);
if(currentCameraFollowUnit->isAlive()==false){
currentCameraFollowUnit=NULL;
getGameCameraPtr()->setState(GameCamera::sGame);
}
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
// Commander
chronoGamePerformanceCounts.start();
if(pendingQuitError == false) {
commander.signalNetworkUpdate(this);
}
addPerformanceCount("ProcessNetworkUpdate",chronoGamePerformanceCounts.getMillis());
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
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);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
//Gui
chronoGamePerformanceCounts.start();
gui.update();
addPerformanceCount("ProcessGUIUpdate",chronoGamePerformanceCounts.getMillis());
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);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
//Particle systems
if(weatherParticleSystem != NULL) {
weatherParticleSystem->setPos(gameCamera.getPos());
}
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);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
Renderer &renderer= Renderer::getInstance();
chronoGamePerformanceCounts.start();
renderer.updateParticleManager(rsGame,avgRenderFps);
addPerformanceCount("ProcessParticleManager",chronoGamePerformanceCounts.getMillis());
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);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
//good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
}
}
while (commander.hasReplayCommandListForFrame() == true);
}
//else if(role == nrClient) {
else {
if(pendingQuitError == false) {
commander.signalNetworkUpdate(this);
}
if(playingStaticVideo == true) {
if(videoPlayer->isPlaying() == false) {
playingStaticVideo = false;
tryPauseToggle(false);
}
}
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
chronoGamePerformanceCounts.start();
//call the chat manager
chatManager.updateNetwork();
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
updateNetworkMarkedCells();
updateNetworkUnMarkedCells();
updateNetworkHighligtedCells();
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
//check for quiting status
if(NetworkManager::getInstance().getGameNetworkInterface() != NULL &&
NetworkManager::getInstance().getGameNetworkInterface()->getQuit() &&
mainMessageBox.getEnabled() == false &&
errorMessageBox.getEnabled() == false) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
quitTriggeredIndicator = true;
return;
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
addPerformanceCount("ProcessMiscNetwork",chronoGamePerformanceCounts.getMillis());
// START - Handle joining in progress games
if(role == nrServer) {
if(this->networkPauseGameForLaggedClientsRequested == true) {
this->networkPauseGameForLaggedClientsRequested = false;
if(getPaused() == false) {
printf("[CMDR] Pausing game for lagging client(s), current world frame [%d]\n",world.getFrameCount());
commander.tryPauseGame(false,false);
}
}
else if(this->networkResumeGameForLaggedClientsRequested == true) {
this->networkResumeGameForLaggedClientsRequested = false;
if(getPaused() == true) {
printf("[CMDR] Resuming game after Pause for lagging client(s), current world frame [%d]\n",world.getFrameCount());
commander.tryResumeGame(false,false);
}
}
ServerInterface *server = NetworkManager::getInstance().getServerInterface();
if(server->getPauseForInGameConnection() == true) {
bool clientNeedsGameSetup = false;
for(int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
if(slot != NULL && slot->getPauseForInGameConnection() == true) {
clientNeedsGameSetup = true;
break;
}
}
if(pausedForJoinGame == false || clientNeedsGameSetup == true) {
//printf("================= Switching player pausing game\n");
for(int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
//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));
//printf("Slot: %d faction name: %s\n",i,faction->getType()->getName().c_str());
if( faction->getControlType() != ctNetwork &&
faction->getControlType() != ctHuman &&
server->isClientConnected(faction->getStartLocationIndex()) == true) {
//printf("Switching player %d from: %d to %d\n",i,faction->getControlType(),ctNetwork);
//printf("Slot: %d faction name: %s GS faction: %s\n",i,faction->getType()->getName().c_str(),server->gameSettings.getFactionTypeName(i).c_str());
server->gameSettings.setFactionControl(i,ctNetwork);
MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
server->gameSettings.setNetworkPlayerName(i,slot->getName());
server->gameSettings.setNetworkPlayerUUID(i,slot->getUUID());
server->gameSettings.setNetworkPlayerPlatform(i,slot->getPlatform());
safeMutex.ReleaseLock();
server->gameSettings.setNetworkPlayerStatuses(i,npst_None);
this->gameSettings.setFactionControl(i,ctNetwork);
this->gameSettings.setNetworkPlayerName(i,server->gameSettings.getNetworkPlayerName(i));
this->gameSettings.setNetworkPlayerUUID(i,server->gameSettings.getNetworkPlayerUUID(i));
this->gameSettings.setNetworkPlayerPlatform(i,server->gameSettings.getNetworkPlayerPlatform(i));
this->gameSettings.setNetworkPlayerStatuses(i,npst_None);
}
}
//printf("#1 Data synch: lmap %u ltile: %d ltech: %u\n",gameSettings.getMapCRC(),gameSettings.getTilesetCRC(),gameSettings.getTechCRC());
//printf("#2 Data synch: lmap %u ltile: %d ltech: %u\n",server->gameSettings.getMapCRC(),server->gameSettings.getTilesetCRC(),server->gameSettings.getTechCRC());
server->broadcastGameSetup(&server->gameSettings,true);
}
for(int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
if(slot != NULL && slot->getPauseForInGameConnection() == true) {
slot->setPauseForInGameConnection(false);
}
}
}
else if(server->getStartInGameConnectionLaunch() == true) {
//printf("^^^ getStartInGameConnectionLaunch triggered!\n");
//server->setStartInGameConnectionLaunch(false);
//this->speed = 1;
//Lang &lang= Lang::getInstance();
bool pauseAndSaveGameForNewClient = false;
for(int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
if(slot != NULL && slot->getStartInGameConnectionLaunch() == true) {
//slot->setStartInGameConnectionLaunch(false);
pauseAndSaveGameForNewClient = true;
}
if(slot != NULL && slot->getJoinGameInProgress() == true) {
//printf("$$$ signalling client to start game [deleting AI player] factionIndex: %d slot: %d startlocation: %d!\n",i,slot->getPlayerIndex(),faction->getStartLocationIndex());
safeMutex.ReleaseLock();
this->gameSettings.setFactionControl(i,ctNetwork);
this->gameSettings.setNetworkPlayerName(i,server->gameSettings.getNetworkPlayerName(i));
this->gameSettings.setNetworkPlayerUUID(i,server->gameSettings.getNetworkPlayerUUID(i));
this->gameSettings.setNetworkPlayerPlatform(i,server->gameSettings.getNetworkPlayerPlatform(i));
if(this->gameSettings.getNetworkPlayerStatuses(i) == npst_Disconnected) {
this->gameSettings.setNetworkPlayerStatuses(i,npst_None);
}
//printf("START Purging AI player for index: %d\n",i);
masterController.clearSlaves(true);
delete aiInterfaces[i];
aiInterfaces[i] = NULL;
//printf("END Purging AI player for index: %d\n",i);
Faction *faction = world.getFaction(i);
faction->setControlType(ctNetwork);
//pauseAndSaveGameForNewClient = true;
}
else if((slot == NULL || slot->isConnected() == false) &&
this->gameSettings.getFactionControl(i) == ctNetwork &&
aiInterfaces[i] == NULL) {
safeMutex.ReleaseLock();
faction->setFactionDisconnectHandled(false);
//this->gameSettings.setNetworkPlayerName(i,lang.getString("AI") + intToStr(i+1));
//server->gameSettings.setNetworkPlayerName(i,lang.getString("AI") + intToStr(i+1));
}
else {
safeMutex.ReleaseLock();
}
}
if(pauseAndSaveGameForNewClient == true && pausedForJoinGame == false &&
pauseRequestSent == false) {
//printf("Pausing game for join in progress game...\n");
commander.tryPauseGame(true,true);
pauseRequestSent = true;
return;
}
}
//else if(server->getPauseForInGameConnection() == true && paused == true &&
if(pausedForJoinGame == true) {
if(pauseStateChanged == true) {
pauseStateChanged = false;
}
if(server->getUnPauseForInGameConnection() == true) {
//printf("^^^ getUnPauseForInGameConnection triggered!\n");
for(int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
if(slot != NULL && slot->getUnPauseForInGameConnection() == true) {
slot->setUnPauseForInGameConnection(false);
faction->setFactionDisconnectHandled(false);
}
}
//printf("Resuming game for join in progress game resumeRequestSent: %d...\n",resumeRequestSent);
if(pausedBeforeJoinGame == false && resumeRequestSent == false) {
commander.tryResumeGame(true,true);
resumeRequestSent = true;
}
}
else if(server->getStartInGameConnectionLaunch() == true) {
bool saveNetworkGame = false;
ServerInterface *server = NetworkManager::getInstance().getServerInterface();
for(int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
if(slot != NULL && slot->getJoinGameInProgress() == true &&
slot->getStartInGameConnectionLaunch() == true &&
slot->getSentSavedGameInfo() == false) {
slot->setStartInGameConnectionLaunch(false);
saveNetworkGame = true;
break;
}
}
if(saveNetworkGame == true) {
//printf("Saved network game to disk\n");
string file = this->saveGame(GameConstants::saveNetworkGameFileServer,"temp/");
string saveGameFilePath = "temp/";
string saveGameFileCompressed = saveGameFilePath + string(GameConstants::saveNetworkGameFileServerCompressed);
if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
saveGameFilePath = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + saveGameFilePath;
saveGameFileCompressed = saveGameFilePath + string(GameConstants::saveNetworkGameFileServerCompressed);
}
else {
string userData = Config::getInstance().getString("UserData_Root","");
if(userData != "") {
endPathWithSlash(userData);
}
saveGameFilePath = userData + saveGameFilePath;
saveGameFileCompressed = saveGameFilePath + string(GameConstants::saveNetworkGameFileServerCompressed);
}
bool compressed_result = compressFileToZIPFile(
file, saveGameFileCompressed);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Saved game [%s] compressed to [%s] returned: %d\n",file.c_str(),saveGameFileCompressed.c_str(), compressed_result);
char szBuf[8096]="";
Lang &lang= Lang::getInstance();
snprintf(szBuf,8096,lang.getString("GameSaved","",true).c_str(),file.c_str());
console.addLine(szBuf);
for(int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
if(slot != NULL && slot->getJoinGameInProgress() == true &&
slot->getSentSavedGameInfo() == false) {
safeMutex.ReleaseLock();
NetworkMessageReady networkMessageReady(0);
slot->sendMessage(&networkMessageReady);
slot = server->getSlot(faction->getStartLocationIndex(),false);
if(slot != NULL) {
slot->setSentSavedGameInfo(true);
}
}
}
}
}
}
//else {
// handle setting changes from clients
Map *map= world.getMap();
//printf("switchSetupRequests != NULL\n");
bool switchRequested = switchSetupForSlots(server, 0, map->getMaxPlayers(), false);
switchRequested = switchRequested || switchSetupForSlots(server, map->getMaxPlayers(), GameConstants::maxPlayers, true);
if(switchRequested == true) {
//printf("Send new game setup from switch: %d\n",switchRequested);
//for(int i= 0; i < gameSettings.getFactionCount(); ++i) {
//printf("#1 Faction Index: %d control: %d startlocation: %d\n",i,gameSettings.getFactionControl(i),gameSettings.getStartLocationIndex(i));
//printf("#2 Faction Index: %d control: %d startlocation: %d\n",i,server->gameSettings.getFactionControl(i),server->gameSettings.getStartLocationIndex(i));
//}
server->broadcastGameSetup(&server->gameSettings,true);
}
//}
// Make the server wait a bit for clients to start.
if(pausedForJoinGame == false && resumeRequestSent == true) {
resumeRequestSent = false;
//sleep(500);
}
}
// END - Handle joining in progress games
//update auto test
if(Config::getInstance().getBool("AutoTest")){
AutoTest::getInstance().updateGame(this);
return;
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
if(world.getQueuedScenario() != "") {
string name = world.getQueuedScenario();
bool keepFactions = world.getQueuedScenarioKeepFactions();
world.setQueuedScenario("",false);
//vector<string> results;
const vector<string> &dirList = Config::getInstance().getPathListForType(ptScenarios);
string scenarioFile = Scenario::getScenarioPath(dirList, name);
try {
gameStarted = false;
//printf("\nname [%s] scenarioFile [%s] results.size() = " MG_SIZE_T_SPECIFIER "\n",name.c_str(),scenarioFile.c_str(),results.size());
//printf("[%s:%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
bool isTutorial = Scenario::isGameTutorial(scenarioFile);
ScenarioInfo scenarioInfo;
Scenario::loadScenarioInfo(scenarioFile, &scenarioInfo, isTutorial);
//printf("[%s:%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
GameSettings gameSettings;
Scenario::loadGameSettings(dirList,&scenarioInfo, &gameSettings, scenarioFile);
//Program *program = world->getGame()->getProgram();
//program->setState(new Game(program, &gameSettings, false));
//world->end();
//world->getMapPtr()->end();
//world.end();
if(keepFactions == false) {
world.end();
world.cleanup();
world.clearTileset();
SoundRenderer::getInstance().stopAllSounds();
masterController.clearSlaves(true);
deleteValues(aiInterfaces.begin(), aiInterfaces.end());
aiInterfaces.clear();
gui.end(); //selection must be cleared before deleting units
world.end(); //must die before selection because of referencers
BaseColorPickEntity::resetUniqueColors();
// MUST DO THIS LAST!!!! Because objects above have pointers to things like
// unit particles and fade them out etc and this end method deletes the original
// object pointers.
Renderer &renderer= Renderer::getInstance();
renderer.endGame(true);
GameConstants::updateFps = original_updateFps;
GameConstants::cameraFps = original_cameraFps;
this->setGameSettings(&gameSettings);
this->resetMembers();
this->load();
this->init();
}
else {
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
//printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
if(currentAmbientSound) {
soundRenderer.stopAmbient(currentAmbientSound);
}
//soundRenderer.stopAllSounds();
soundRenderer.stopAllSounds(fadeMusicMilliseconds);
world.endScenario();
BaseColorPickEntity::resetUniqueColors();
Renderer &renderer= Renderer::getInstance();
renderer.endScenario();
world.clearTileset();
this->setGameSettings(&gameSettings);
this->load(lgt_FactionPreview | lgt_TileSet | lgt_Map | lgt_Scenario);
try {
world.init(this, gameSettings.getDefaultUnits(),false);
}
catch(const exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
if(errorMessageBox.getEnabled() == false) {
ErrorDisplayMessage(ex.what(),true);
}
}
world.initUnitsForScenario();
Map *map= world.getMap();
gameCamera.init(map->getW(), map->getH());
// camera default height calculation
if(map->getCameraHeight()>0 && gameCamera.getCalculatedDefault()<map->getCameraHeight()){
gameCamera.setCalculatedDefault(map->getCameraHeight());
}
else if(gameCamera.getCalculatedDefault()<map->getMaxMapHeight()+13.0f){
gameCamera.setCalculatedDefault(map->getMaxMapHeight()+13.0f);
}
scriptManager.init(&world, &gameCamera,loadGameNode);
renderer.initGame(this,this->getGameCameraPtr());
//sounds
//soundRenderer.stopAllSounds(fadeMusicMilliseconds);
//soundRenderer.stopAllSounds();
//soundRenderer= SoundRenderer::getInstance();
Tileset *tileset= world.getTileset();
AmbientSounds *ambientSounds= tileset->getAmbientSounds();
//rain
if(tileset->getWeather() == wRainy && ambientSounds->isEnabledRain()) {
//logger.add("Starting ambient stream", true);
currentAmbientSound = ambientSounds->getRain();
//printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
soundRenderer.playAmbient(currentAmbientSound);
}
//snow
if(tileset->getWeather() == wSnowy && ambientSounds->isEnabledSnow()) {
//logger.add("Starting ambient stream", true);
currentAmbientSound = ambientSounds->getSnow();
//printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
soundRenderer.playAmbient(currentAmbientSound);
}
if(this->masterserverMode == false) {
StrSound *gameMusic= world.getThisFaction()->getType()->getMusic();
soundRenderer.playMusic(gameMusic);
}
gameStarted = true;
}
//this->init();
//printf("[%s:%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//Checksum checksum;
//world->loadScenario(scenarioFile, &checksum, true);
}
#if defined(WIN32)
catch(const exception) {
#else
catch(const exception &ex) {
#endif
gameStarted = true;
totalRenderFps++;
throw;
}
}
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
perfList.push_back(perfBuf);
}
if(showPerfStats && chronoPerf.getMillis() >= 50) {
for(unsigned int x = 0; x < (unsigned int)perfList.size(); ++x) {
printf("%s",perfList[x].c_str());
}
}
}
catch(const exception &ex) {
quitPendingIndicator = true;
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
//printf("#100 quitPendingIndicator = %d, errorMessageBox.getEnabled() = %d\n",quitPendingIndicator,errorMessageBox.getEnabled());
NetworkManager &networkManager= NetworkManager::getInstance();
if(networkManager.getGameNetworkInterface() != NULL) {
GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
networkInterface->sendTextMessage(szBuf,-1,true,"");
sleep(10);
networkManager.getGameNetworkInterface()->quitGame(true);
}
if(errorMessageBox.getEnabled() == false) {
ErrorDisplayMessage(ex.what(),true);
}
}
}
void Game::addPerformanceCount(string key,int64 value) {
gamePerformanceCounts[key] = value + gamePerformanceCounts[key] / 2;
}
string Game::getGamePerformanceCounts(bool displayWarnings) const {
if(gamePerformanceCounts.empty() == true) {
return "";
}
bool displayWarningHeader = true;
bool WARN_TO_CONSOLE = Config::getInstance().getBool("PerformanceWarningEnabled","false");
int WARNING_MILLIS = Config::getInstance().getInt("PerformanceWarningMillis","7");
int WARNING_RENDER_MILLIS = Config::getInstance().getInt("PerformanceWarningRenderMillis","40");
string result = "";
for(std::map<string,int64>::const_iterator iterMap = gamePerformanceCounts.begin();
iterMap != gamePerformanceCounts.end(); ++iterMap) {
if(iterMap->first == ProgramState::MAIN_PROGRAM_RENDER_KEY) {
if(iterMap->second < WARNING_RENDER_MILLIS) {
continue;
}
//else {
// printf("iterMap->second: " MG_I64_SPECIFIER " WARNING_RENDER_MILLIS = %d\n",iterMap->second,WARNING_RENDER_MILLIS);
//}
}
else if(iterMap->second < WARNING_MILLIS) {
continue;
}
if(result != "") {
result += "\n";
}
string perfStat = iterMap->first + " = avg millis: " + intToStr(iterMap->second);
if(displayWarnings == true && WARN_TO_CONSOLE == true) {
if(displayWarningHeader == true) {
displayWarningHeader = false;
printf("=====================================\nPERFORMANCE WARNINGS for World Frame: %d\n",world.getFrameCount());
}
printf("*PERFORMANCE WARNING* %s\n",perfStat.c_str());
}
result += perfStat;
}
return result;
}
bool Game::switchSetupForSlots(ServerInterface *& serverInterface,
int startIndex, int endIndex, bool onlyNetworkUnassigned) {
bool switchRequested = false;
if(serverInterface == NULL) {
return switchRequested;
}
MutexSafeWrapper safeMutex(serverInterface->getSwitchSetupRequestsMutex(),CODE_AT_LINE);
SwitchSetupRequest ** switchSetupRequests = serverInterface->getSwitchSetupRequests();
if(switchSetupRequests == NULL) {
return switchRequested;
}
Map *map= world.getMap();
for(int i= startIndex; i < endIndex; ++i) {
if(switchSetupRequests[i] != NULL) {
//printf("Faction Index: %d Switch slot = %d to = %d current control = %d\n",i,switchSetupRequests[i]->getCurrentSlotIndex(),switchSetupRequests[i]->getToSlotIndex(),gameSettings.getFactionControl(i));
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());
if(onlyNetworkUnassigned == true && gameSettings.getFactionControl(i) != ctNetworkUnassigned) {
if(i < map->getMaxPlayers() || (i >= map->getMaxPlayers() && gameSettings.getFactionControl(i) != ctNetwork)) {
continue;
}
}
if(gameSettings.getFactionControl(i) == ctNetwork ||
gameSettings.getFactionControl(i) == ctNetworkUnassigned ||
//(gameSettings.getFactionControl(i) != ctClosed && gameSettings.getFactionControl(i) != ctHuman)) {
(gameSettings.getFactionControl(i) != ctHuman)) {
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());
if(switchSetupRequests[i]->getToSlotIndex() != -1) {
int newSlotIdx = switchSetupRequests[i]->getToSlotIndex();
//printf("switchSlot request from %d to %d\n",switchSetupRequests[i]->getCurrentSlotIndex(),switchSetupRequests[i]->getToSlotIndex());
int switchSlotIdx = switchSetupRequests[i]->getCurrentSlotIndex();
if(serverInterface->switchSlot(switchSlotIdx,newSlotIdx)) {
//printf("switchSlot returned true\n");
switchRequested = true;
int oldFactionIndex = gameSettings.getFactionIndexForStartLocation(switchSlotIdx);
int newFactionIndex = gameSettings.getFactionIndexForStartLocation(newSlotIdx);
//printf("Switching faction for index %d [%d] to %d\n",newSlotIdx,switchSlotIdx,gameSettings.getFactionControl(newFactionIndex));
gameSettings.setNetworkPlayerName(oldFactionIndex, "");
serverInterface->gameSettings.setNetworkPlayerName(oldFactionIndex, "");
gameSettings.setNetworkPlayerUUID(oldFactionIndex, "");
serverInterface->gameSettings.setNetworkPlayerUUID(oldFactionIndex, "");
gameSettings.setNetworkPlayerPlatform(oldFactionIndex, "");
serverInterface->gameSettings.setNetworkPlayerPlatform(oldFactionIndex, "");
gameSettings.setFactionControl(newFactionIndex,ctNetwork);
serverInterface->gameSettings.setFactionControl(newFactionIndex,ctNetwork);
//printf("#1a Faction Index: %d control: %d startlocation: %d\n",newFactionIndex,gameSettings.getFactionControl(newFactionIndex),gameSettings.getStartLocationIndex(newFactionIndex));
//printf("#2a Faction Index: %d control: %d startlocation: %d\n",newFactionIndex,serverInterface->gameSettings.getFactionControl(newFactionIndex),serverInterface->gameSettings.getStartLocationIndex(newFactionIndex));
try {
//if(switchSetupRequests[i]->getSelectedFactionName() != "") {
// listBoxFactions[newFactionIdx].setSelectedItem(switchSetupRequests[i]->getSelectedFactionName());
//}
//if(switchSetupRequests[i]->getToTeam() != -1) {
// listBoxTeams[newFactionIdx].setSelectedItemIndex(switchSetupRequests[i]->getToTeam());
//}
if(switchSetupRequests[i]->getNetworkPlayerName() != "") {
//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());
gameSettings.setNetworkPlayerName(newFactionIndex,switchSetupRequests[i]->getNetworkPlayerName());
serverInterface->gameSettings.setNetworkPlayerName(newFactionIndex,switchSetupRequests[i]->getNetworkPlayerName());
}
// if(gameSettings.getFactionControl(switchFactionIdx) == ctNetworkUnassigned) {
// serverInterface->removeSlot(switchFactionIdx);
// //listBoxControls[switchFactionIdx].setSelectedItemIndex(ctClosed);
// gameSettings.getFactionControl(switchFactionIdx)
//
// labelPlayers[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players);
// labelPlayerNames[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players);
// listBoxControls[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players);
// listBoxFactions[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players);
// listBoxTeams[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players);
// labelNetStatus[switchSlotIdx].setVisible(switchSlotIdx+1 <= mapInfo.players);
// }
}
catch(const runtime_error &e) {
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
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());
}
}
//printf("AFTER switchSlot returned\n");
}
else {
try {
//if(switchSetupRequests[i]->getSelectedFactionName() != "") {
// listBoxFactions[i].setSelectedItem(switchSetupRequests[i]->getSelectedFactionName());
//}
//if(switchSetupRequests[i]->getToTeam() != -1) {
// listBoxTeams[i].setSelectedItemIndex(switchSetupRequests[i]->getToTeam());
//}
if((switchSetupRequests[i]->getSwitchFlags() & ssrft_NetworkPlayerName) == ssrft_NetworkPlayerName) {
//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());
if(switchSetupRequests[i]->getNetworkPlayerName() != GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) {
//labelPlayerNames[i].setText(switchSetupRequests[i]->getNetworkPlayerName());
gameSettings.setNetworkPlayerName(i,switchSetupRequests[i]->getNetworkPlayerName());
serverInterface->gameSettings.setNetworkPlayerName(i,switchSetupRequests[i]->getNetworkPlayerName());
switchRequested = true;
}
else {
//labelPlayerNames[i].setText("");
gameSettings.setNetworkPlayerName(i,"");
serverInterface->gameSettings.setNetworkPlayerName(i,"");
switchRequested = true;
}
//SetActivePlayerNameEditor();
//switchSetupRequests[i]->clearSwitchFlag(ssrft_NetworkPlayerName);
}
}
catch(const runtime_error &e) {
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
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());
}
}
}
delete switchSetupRequests[i];
switchSetupRequests[i]=NULL;
}
}
return switchRequested;
}
void Game::updateNetworkMarkedCells() {
try {
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
if(gameNetworkInterface != NULL &&
gameNetworkInterface->getMarkedCellList(false).empty() == false) {
std::vector<MarkedCell> chatList = gameNetworkInterface->getMarkedCellList(true);
for(int idx = 0; idx < (int)chatList.size(); idx++) {
MarkedCell mc = chatList[idx];
if(mc.getFactionIndex() >= 0) {
mc.setFaction((const Faction *)world.getFaction(mc.getFactionIndex()));
}
Map *map= world.getMap();
Vec2i surfaceCellPos = map->toSurfCoords(mc.getTargetPos());
mapMarkedCellList[surfaceCellPos] = mc;
}
}
}
catch(const std::exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
throw megaglest_runtime_error(szBuf);
}
}
void Game::updateNetworkUnMarkedCells() {
try {
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
if(gameNetworkInterface != NULL &&
gameNetworkInterface->getUnMarkedCellList(false).empty() == false) {
//Lang &lang= Lang::getInstance();
std::vector<UnMarkedCell> chatList = gameNetworkInterface->getUnMarkedCellList(true);
for(int idx = 0; idx < (int)chatList.size(); idx++) {
UnMarkedCell mc = chatList[idx];
mc.setFaction((const Faction *)world.getFaction(mc.getFactionIndex()));
Map *map= world.getMap();
Vec2i surfaceCellPos = map->toSurfCoords(mc.getTargetPos());
mapMarkedCellList.erase(surfaceCellPos);
}
}
}
catch(const std::exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
throw megaglest_runtime_error(szBuf);
}
}
void Game::updateNetworkHighligtedCells() {
try {
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
//update the current entries
for(int idx = (int)highlightedCells.size()-1; idx >= 0; idx--) {
MarkedCell *mc = &highlightedCells[idx];
mc->decrementAliveCount();
if(mc->getAliveCount() < 0) {
highlightedCells.erase(highlightedCells.begin()+idx);
}
}
if(gameNetworkInterface != NULL &&
gameNetworkInterface->getHighlightedCellList(false).empty() == false) {
//Lang &lang= Lang::getInstance();
std::vector<MarkedCell> highlighList = gameNetworkInterface->getHighlightedCellList(true);
for(int idx = 0; idx < (int)highlighList.size(); idx++) {
MarkedCell mc = highlighList[idx]; // I want a copy here
if(mc.getFactionIndex() >= 0) {
mc.setFaction((const Faction *)world.getFaction(mc.getFactionIndex())); // set faction pointer
}
addOrReplaceInHighlightedCells(mc);
}
}
}
catch(const std::exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
throw megaglest_runtime_error(szBuf);
}
}
void Game::addOrReplaceInHighlightedCells(MarkedCell mc){
if(mc.getFactionIndex() >= 0) {
for(int i = (int)highlightedCells.size()-1; i >= 0; i--) {
MarkedCell *currentMc = &highlightedCells[i];
if(currentMc->getFactionIndex() == mc.getFactionIndex()) {
highlightedCells.erase(highlightedCells.begin()+i);
}
}
}
if(mc.getAliveCount() <= 0) {
mc.setAliveCount(200);
}
highlightedCells.push_back(mc);
if (this->masterserverMode == false) {
CoreData &coreData= CoreData::getInstance();
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
const Faction *faction = mc.getFaction();
if(getWorld()->getThisFaction() == NULL) {
throw megaglest_runtime_error("getWorld()->getThisFaction() == NULL");
}
//printf("faction [%p][%s]\n",faction,(faction != NULL ? faction->getType()->getName().c_str() : ""));
if((faction == NULL) ||
(faction->getTeam() == getWorld()->getThisFaction()->getTeam())) {
soundRenderer.playFx(coreData.getMarkerSound());
}
}
}
void Game::ReplaceDisconnectedNetworkPlayersWithAI(bool isNetworkGame, NetworkRole role) {
if(role == nrServer && isNetworkGame == true &&
difftime((long int)time(NULL),lastNetworkPlayerConnectionCheck) >= NETWORK_PLAYER_CONNECTION_CHECK_SECONDS) {
lastNetworkPlayerConnectionCheck = time(NULL);
Logger &logger= Logger::getInstance();
ServerInterface *server = NetworkManager::getInstance().getServerInterface();
bool newAIPlayerCreated = false;
for(int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
if( faction->getFactionDisconnectHandled() == false &&
(faction->getControlType() == ctNetwork ||
faction->getControlType() == ctNetworkCpuEasy ||
faction->getControlType() == ctNetworkCpu ||
faction->getControlType() == ctNetworkCpuUltra ||
faction->getControlType() == ctNetworkCpuMega)) {
if(aiInterfaces[i] == NULL &&
server->isClientConnected(faction->getStartLocationIndex()) == false) {
if(faction->getPersonalityType() != fpt_Observer) {
DumpCRCWorldLogIfRequired("_faction_" + intToStr(i));
}
faction->setFactionDisconnectHandled(true);
Lang &lang= Lang::getInstance();
bool isPlayerObserver = false;
char szBuf[8096]="";
if(faction->getPersonalityType() != fpt_Observer) {
aiInterfaces[i] = new AiInterface(*this, i, faction->getTeam(), faction->getStartLocationIndex());
snprintf(szBuf,8096,Lang::getInstance().getString("LogScreenGameLoadingCreatingAIFaction","",true).c_str(),i);
logger.add(szBuf, true);
commander.tryNetworkPlayerDisconnected(i);
newAIPlayerCreated = true;
}
else {
isPlayerObserver = true;
}
const vector<string> languageList = this->gameSettings.getUniqueNetworkPlayerLanguages();
for(unsigned int j = 0; j < (unsigned int)languageList.size(); ++j) {
if(isPlayerObserver == false) {
string msg = "Player #%d [%s] has disconnected, switching player to AI mode!";
if(lang.hasString("GameSwitchPlayerToAI",languageList[j],true)) {
msg = lang.getString("GameSwitchPlayerToAI",languageList[j],true);
}
snprintf(szBuf,8096,msg.c_str(),i+1,this->gameSettings.getNetworkPlayerName(i).c_str());
}
else {
string msg = "Player #%d [%s] has disconnected, but player was only an observer!";
if(lang.hasString("GameSwitchPlayerObserverToAI",languageList[j],true)) {
msg = lang.getString("GameSwitchPlayerObserverToAI",languageList[j],true);
}
snprintf(szBuf,8096,msg.c_str(),i+1,this->gameSettings.getNetworkPlayerName(i).c_str());
}
bool localEcho = (languageList[j] == lang.getLanguage());
server->sendTextMessage(szBuf,-1,localEcho,languageList[j]);
}
}
}
}
if(newAIPlayerCreated == true && Config::getInstance().getBool("EnableNewThreadManager","false") == true) {
bool enableServerControlledAI = this->gameSettings.getEnableServerControlledAI();
masterController.clearSlaves(true);
std::vector<SlaveThreadControllerInterface *> slaveThreadList;
for(int i=0; i < world.getFactionCount(); ++i) {
Faction *faction= world.getFaction(i);
if(faction->getCpuControl(enableServerControlledAI,isNetworkGame,role) == true) {
slaveThreadList.push_back(aiInterfaces[i]->getWorkerThread());
}
}
masterController.setSlaves(slaveThreadList);
}
}
}
void Game::updateCamera(){
if(currentUIState != NULL) {
currentUIState->updateCamera();
return;
}
gameCamera.update();
}
// ==================== render ====================
//render
void Game::render() {
// Ensure the camera starts in the right position
if(isFirstRender == true) {
isFirstRender = false;
if(this->loadGameNode == NULL) {
gameCamera.setState(GameCamera::sGame);
this->restoreToStartXY();
}
}
canRender();
incrementFps();
renderFps++;
totalRenderFps++;
updateWorldStats();
//NetworkManager &networkManager= NetworkManager::getInstance();
if(this->masterserverMode == false) {
renderWorker();
}
else {
// Titi, uncomment this to watch the game on the masterserver
//renderWorker();
// In masterserver mode quit game if no network players left
ServerInterface *server = NetworkManager::getInstance().getServerInterface();
int connectedClients=0;
for(int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
if(server->isClientConnected(faction->getStartLocationIndex()) == true) {
connectedClients++;
}
}
if(connectedClients == 0) {
quitTriggeredIndicator = true;
}
else {
string str="";
std::map<int,string> factionDebugInfo;
if( difftime((long int)time(NULL),lastMasterServerGameStatsDump) >= GAME_STATS_DUMP_INTERVAL) {
lastMasterServerGameStatsDump = time(NULL);
str = getDebugStats(factionDebugInfo);
printf("== Current in-game stats (interval %d) ==\n%s\n",GAME_STATS_DUMP_INTERVAL,str.c_str());
}
}
}
}
void Game::renderWorker() {
if(currentUIState != NULL) {
// Renderer &renderer= Renderer::getInstance();
// renderer.clearBuffers();
//
// //3d
// renderer.reset3dMenu();
//
// renderer.clearZBuffer();
// //renderer.loadCameraMatrix(menuBackground.getCamera());
// //renderer.renderMenuBackground(&menuBackground);
// renderer.renderParticleManager(rsMenu);
//
// //2d
// renderer.reset2d();
//
// currentUIState->render();
//
// if(renderer.isMasterserverMode() == false) {
// renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim);
// renderer.renderFPSWhenEnabled(lastFps);
// renderer.swapBuffers();
// }
currentUIState->render();
return;
}
else {
Renderer &renderer= Renderer::getInstance();
if(renderer.getCustom3dMenu() != NULL) {
renderer.setCustom3dMenu(NULL);
}
}
Chrono chrono;
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
render3d();
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
render2d();
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
Renderer::getInstance().swapBuffers();
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());
}
// ==================== tick ====================
void Game::removeUnitFromSelection(const Unit *unit) {
try {
Selection *selection= gui.getSelectionPtr();
for(int i=0; i < selection->getCount(); ++i) {
const Unit *currentUnit = selection->getUnit(i);
if(currentUnit == unit) {
selection->unSelect(i);
break;
}
}
}
catch(const exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
if(errorMessageBox.getEnabled() == false) {
ErrorDisplayMessage(ex.what(),true);
}
//abort();
}
}
bool Game::addUnitToSelection(Unit *unit) {
bool result = false;
try {
Selection *selection= gui.getSelectionPtr();
if(selection != NULL) {
result = selection->select(unit);
}
}
catch(const exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
if(errorMessageBox.getEnabled() == false) {
ErrorDisplayMessage(ex.what(),true);
}
//abort();
}
return result;
}
void Game::addUnitToGroupSelection(Unit *unit,int groupIndex) {
try {
Selection *selection= gui.getSelectionPtr();
if(selection != NULL) {
selection->addUnitToGroup(groupIndex,unit);
}
}
catch(const exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
if(errorMessageBox.getEnabled() == false) {
ErrorDisplayMessage(ex.what(),true);
}
//abort();
}
}
void Game::removeUnitFromGroupSelection(int unitId,int groupIndex) {
try {
Selection *selection= gui.getSelectionPtr();
if(selection != NULL) {
selection->removeUnitFromGroup(groupIndex,unitId);
}
}
catch(const exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
if(errorMessageBox.getEnabled() == false) {
ErrorDisplayMessage(ex.what(),true);
}
//abort();
}
}
void Game::recallGroupSelection(int groupIndex) {
try {
Selection *selection= gui.getSelectionPtr();
if(selection != NULL) {
selection->recallGroup(groupIndex);
}
}
catch(const exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
if(errorMessageBox.getEnabled() == false) {
ErrorDisplayMessage(ex.what(),true);
}
//abort();
}
}
void Game::tick() {
ProgramState::tick();
tickCount++;
if(avgUpdateFps == -1) {
avgUpdateFps = updateFps;
}
else {
avgUpdateFps = (avgUpdateFps + updateFps) / 2;
}
currentAvgRenderFpsTotal += renderFps;
if(avgRenderFps == -1) {
avgRenderFps = renderFps;
}
// Update the average every x game ticks
const int CHECK_AVG_FPS_EVERY_X_TICKS = 15;
if(tickCount % CHECK_AVG_FPS_EVERY_X_TICKS == 0) {
avgRenderFps = currentAvgRenderFpsTotal / CHECK_AVG_FPS_EVERY_X_TICKS;
currentAvgRenderFpsTotal = 0;
}
if(captureAvgTestStatus == true) {
if(updateFpsAvgTest == -1) {
updateFpsAvgTest = updateFps;
}
else {
updateFpsAvgTest = (updateFpsAvgTest + updateFps) / 2;
}
if(renderFpsAvgTest == -1) {
renderFpsAvgTest = renderFps;
}
else {
renderFpsAvgTest = (renderFpsAvgTest + renderFps) / 2;
}
}
lastUpdateFps= updateFps;
lastRenderFps= renderFps;
updateFps= 0;
renderFps= 0;
//Win/lose check
checkWinner();
gui.tick();
}
// ==================== events ====================
int Game::getFirstUnusedTeamNumber() {
std::map<int,bool> uniqueTeamNumbersUsed;
for(unsigned int i = 0; i < (unsigned int)world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
uniqueTeamNumbersUsed[faction->getTeam()]=true;
}
int result = -1;
for(int i = 0; i < GameConstants::maxPlayers; ++i) {
if(uniqueTeamNumbersUsed.find(i) == uniqueTeamNumbersUsed.end()) {
result = i;
break;
}
}
return result;
}
void Game::setupRenderForVideo() {
Renderer &renderer= Renderer::getInstance();
//renderer.clearBuffers();
//3d
//renderer.reset3dMenu();
//renderer.clearZBuffer();
//2d
//renderer.reset2d();
renderer.setupRenderForVideo();
}
void Game::tryPauseToggle(bool pauseValue) {
bool allowAdminMenuItems = false;
NetworkManager &networkManager= NetworkManager::getInstance();
NetworkRole role = networkManager.getNetworkRole();
if(role == nrServer) {
allowAdminMenuItems = true;
}
else if(role == nrClient) {
ClientInterface *clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
if(clientInterface != NULL &&
gameSettings.getMasterserver_admin() == clientInterface->getSessionKey()) {
allowAdminMenuItems = true;
}
}
bool isNetworkGame = this->gameSettings.isNetworkGame();
//printf("Try Pause allowAdminMenuItems = %d, pauseValue = %d\n",allowAdminMenuItems,pauseValue);
if(allowAdminMenuItems) {
if(pauseValue == true) {
commander.tryPauseGame(false,false);
}
else {
if(isNetworkGame == false) {
setPaused(pauseValue, true,false,false);
}
else {
commander.tryResumeGame(false,false);
}
}
}
}
void Game::startMarkCell() {
int totalMarkedCellsForPlayer = 0;
if(world.getThisFaction() != NULL) {
for(std::map<Vec2i, MarkedCell>::iterator iterMap = mapMarkedCellList.begin();
iterMap != mapMarkedCellList.end(); ++iterMap) {
MarkedCell &bm = iterMap->second;
if(bm.getPlayerIndex() == world.getThisFaction()->getStartLocationIndex()) {
totalMarkedCellsForPlayer++;
}
}
}
const int MAX_MARKER_COUNT = 5;
if(totalMarkedCellsForPlayer < MAX_MARKER_COUNT) {
isMarkCellEnabled = true;
}
else {
Lang &lang= Lang::getInstance();
console.addLine(lang.getString("MaxMarkerCount") + " " + intToStr(MAX_MARKER_COUNT));
}
}
void Game::processInputText(string text, bool cancelled) {
isMarkCellTextEnabled = false;
if(cancelled == false) {
//printf("Note [%s]\n",text.c_str());
cellMarkedData.setNote(text);
addCellMarker(cellMarkedPos, cellMarkedData);
// if(text.find("\\n") != text.npos) {
// replaceAll(text, "\\n", "\n");
// }
// if(text.find("\\t") != text.npos) {
// replaceAll(text, "\\t", "\t");
// }
//
// cellMarkedData.setNote(text);
// mapMarkedCellList[cellMarkedPos] = cellMarkedData;
//
// GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
//
// int factionIndex = -1;
// int playerIndex = -1;
// if(cellMarkedData.getFaction() != NULL) {
// factionIndex = cellMarkedData.getFaction()->getIndex();
// playerIndex = cellMarkedData.getFaction()->getStartLocationIndex();
// }
// gameNetworkInterface->sendMarkCellMessage(
// cellMarkedData.getTargetPos(),
// factionIndex,
// cellMarkedData.getNote(),
// playerIndex);
//
// Renderer &renderer= Renderer::getInstance();
// renderer.forceQuadCacheUpdate();
}
}
void Game::addCellMarker(Vec2i cellPos, MarkedCell cellData) {
//printf("Note [%s]\n",text.c_str());
string text = cellData.getNote();
if(text.find("\\n") != text.npos) {
replaceAll(text, "\\n", "\n");
}
if(text.find("\\t") != text.npos) {
replaceAll(text, "\\t", "\t");
}
cellData.setNote(text);
mapMarkedCellList[cellPos] = cellData;
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
int factionIndex = -1;
int playerIndex = -1;
if(cellData.getFaction() != NULL) {
factionIndex = cellData.getFaction()->getIndex();
playerIndex = cellData.getFaction()->getStartLocationIndex();
}
//printf("Adding Cell marker pos [%s] factionIndex [%d] note [%s] playerIndex = %d\n",cellData.getTargetPos().getString().c_str(),factionIndex,cellData.getNote().c_str(),playerIndex);
gameNetworkInterface->sendMarkCellMessage(
cellData.getTargetPos(),
factionIndex,
cellData.getNote(),
playerIndex);
Renderer &renderer= Renderer::getInstance();
renderer.forceQuadCacheUpdate();
}
void Game::removeCellMarker(Vec2i surfaceCellPos, const Faction *faction) {
//Vec2i surfaceCellPos = map->toSurfCoords(Vec2i(xCell,yCell));
Map *map= world.getMap();
SurfaceCell *sc = map->getSurfaceCell(surfaceCellPos);
Vec3f vertex = sc->getVertex();
Vec2i targetPos(vertex.x,vertex.z);
//printf("Remove Cell marker lookup pos [%s] factionIndex [%d]\n",surfaceCellPos.getString().c_str(),(faction != NULL ? faction->getIndex() : -1));
if(mapMarkedCellList.find(surfaceCellPos) != mapMarkedCellList.end()) {
MarkedCell mc = mapMarkedCellList[surfaceCellPos];
if(mc.getFaction() == faction) {
mapMarkedCellList.erase(surfaceCellPos);
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
int factionIndex = (faction != NULL ? faction->getIndex() : -1);
//printf("Remvoing Cell marker pos [%s] factionIndex [%d] note [%s]\n",mc.getTargetPos().getString().c_str(),factionIndex,mc.getNote().c_str());
gameNetworkInterface->sendUnMarkCellMessage(mc.getTargetPos(),factionIndex);
}
}
//printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size());
//isUnMarkCellEnabled = false;
Renderer &renderer= Renderer::getInstance();
//renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos);
renderer.forceQuadCacheUpdate();
}
void Game::showMarker(Vec2i cellPos, MarkedCell cellData) {
//setMarker = true;
//if(setMarker) {
//Vec2i targetPos = cellData.targetPos;
//Vec2i screenPos(x,y-60);
//Renderer &renderer= Renderer::getInstance();
//renderer.computePosition(screenPos, targetPos);
//Vec2i surfaceCellPos = map->toSurfCoords(targetPos);
//MarkedCell mc(targetPos,world.getThisFaction(),"none",world.getThisFaction()->getStartLocationIndex());
addOrReplaceInHighlightedCells(cellData);
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
gameNetworkInterface->sendHighlightCellMessage(cellData.getTargetPos(),cellData.getFactionIndex());
//}
}
void Game::mouseDownLeft(int x, int y) {
if(this->masterserverMode == true) {
return;
}
cameraDragAllowed=false;
if(currentUIState != NULL) {
currentUIState->mouseDownLeft(x, y);
return;
}
try {
if(gameStarted == false || totalRenderFps <= 0) {
Logger::getInstance().handleMouseClick(x, y);
return;
}
Map *map= world.getMap();
const Metrics &metrics= Metrics::getInstance();
NetworkManager &networkManager= NetworkManager::getInstance();
bool messageBoxClick= false;
bool originalIsMarkCellEnabled = isMarkCellEnabled;
bool originalIsUnMarkCellEnabled = isUnMarkCellEnabled;
if(popupMenu.mouseClick(x, y)) {
std::pair<int,string> result = popupMenu.mouseClickedMenuItem(x, y);
//printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first);
//printf("popupMenu.mouseClick == true result.first = %d disconnectPlayerPopupMenuIndex = %d\n",result.first,disconnectPlayerPopupMenuIndex);
popupMenu.setEnabled(false);
popupMenu.setVisible(false);
// Exit game
if(result.first == exitGamePopupMenuIndex) {
showMessageBox(Lang::getInstance().getString("ExitGameMenu?"), "", true);
}
else if(result.first == joinTeamPopupMenuIndex) {
Lang &lang= Lang::getInstance();
switchTeamIndexMap.clear();
std::map<int,bool> uniqueTeamNumbersUsed;
std::vector<string> menuItems;
for(unsigned int i = 0; i < (unsigned int)world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
if(faction->getPersonalityType() != fpt_Observer &&
uniqueTeamNumbersUsed.find(faction->getTeam()) == uniqueTeamNumbersUsed.end()) {
uniqueTeamNumbersUsed[faction->getTeam()] = true;
}
if(faction->getPersonalityType() != fpt_Observer &&
world.getThisFaction()->getIndex() != faction->getIndex() &&
world.getThisFaction()->getTeam() != faction->getTeam()) {
char szBuf[8096]="";
if(lang.hasString("JoinPlayerTeam") == true) {
snprintf(szBuf,8096,lang.getString("JoinPlayerTeam").c_str(),faction->getIndex(),this->gameSettings.getNetworkPlayerName(i).c_str(),faction->getTeam());
}
else {
snprintf(szBuf,8096,"Join player #%d - %s on Team: %d",faction->getIndex(),this->gameSettings.getNetworkPlayerName(i).c_str(),faction->getTeam());
}
menuItems.push_back(szBuf);
switchTeamIndexMap[(int)menuItems.size()-1] = faction->getTeam();
}
}
if((int)uniqueTeamNumbersUsed.size() < 8) {
menuItems.push_back(lang.getString("CreateNewTeam"));
switchTeamIndexMap[(int)menuItems.size()-1] = CREATE_NEW_TEAM;
}
menuItems.push_back(lang.getString("Cancel"));
switchTeamIndexMap[(int)menuItems.size()-1] = CANCEL_SWITCH_TEAM;
popupMenuSwitchTeams.setW(100);
popupMenuSwitchTeams.setH(100);
popupMenuSwitchTeams.init(lang.getString("SwitchTeams"),menuItems);
popupMenuSwitchTeams.setEnabled(true);
popupMenuSwitchTeams.setVisible(true);
}
else if(result.first == disconnectPlayerPopupMenuIndex) {
Lang &lang= Lang::getInstance();
NetworkManager &networkManager= NetworkManager::getInstance();
NetworkRole role = networkManager.getNetworkRole();
ServerInterface *serverInterface = NULL;
if(role == nrServer) {
serverInterface = dynamic_cast<ServerInterface *>(networkManager.getServerInterface());
}
disconnectPlayerIndexMap.clear();
std::vector<string> menuItems;
for(unsigned int i = 0; i < (unsigned int)world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
//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));
bool isSlotJoinInProgressClient = false;
if(serverInterface != NULL) {
MutexSafeWrapper safeMutex(serverInterface->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
ConnectionSlot *slot = serverInterface->getSlot(faction->getStartLocationIndex(),false);
if(slot != NULL && slot->getConnectHasHandshaked() == true &&
slot->getCurrentFrameCount() <= 0) {
isSlotJoinInProgressClient = true;
}
}
//printf("isSlotJoinInProgressClient: %d [%d] [%d][%d] [%d] [%d] [%d]\n",
// isSlotJoinInProgressClient,faction->getPersonalityType(),faction->getIndex(),world.getThisFaction()->getIndex(),faction->getControlType(),this->gameSettings.getNetworkPlayerStatuses(i),i);
if(isSlotJoinInProgressClient == true ||
(faction->getPersonalityType() != fpt_Observer &&
world.getThisFaction()->getIndex() != faction->getIndex() &&
faction->getControlType() == ctNetwork &&
this->gameSettings.getNetworkPlayerStatuses(i) != npst_Disconnected)) {
char szBuf[8096]="";
if(lang.hasString("DisconnectNetorkPlayerIndex") == true) {
snprintf(szBuf,8096,lang.getString("DisconnectNetorkPlayerIndex").c_str(),faction->getIndex()+1,this->gameSettings.getNetworkPlayerName(i).c_str());
}
else {
snprintf(szBuf,8096,"Disconnect player #%d - %s:",faction->getIndex()+1,this->gameSettings.getNetworkPlayerName(i).c_str());
}
menuItems.push_back(szBuf);
//disconnectPlayerIndexMap[menuItems.size()-1] = faction->getStartLocationIndex();
disconnectPlayerIndexMap[(int)menuItems.size()-1] = faction->getIndex();
}
}
menuItems.push_back(lang.getString("Cancel"));
disconnectPlayerIndexMap[(int)menuItems.size()-1] = CANCEL_DISCONNECT_PLAYER;
popupMenuDisconnectPlayer.setW(100);
popupMenuDisconnectPlayer.setH(100);
popupMenuDisconnectPlayer.init(lang.getString("DisconnectNetorkPlayer"),menuItems);
popupMenuDisconnectPlayer.setEnabled(true);
popupMenuDisconnectPlayer.setVisible(true);
}
else if(result.first == keyboardSetupPopupMenuIndex) {
MainMenu *newMenu = new MainMenu(program); // open keyboard shortcuts setup screen
currentUIState = newMenu;
Renderer &renderer= Renderer::getInstance();
renderer.setCustom3dMenu(newMenu);
//currentUIState->load();
currentUIState->init();
// open keyboard shortcuts setup screen
newMenu->setState(new MenuStateKeysetup(program, newMenu, &currentUIState));
}
else if(result.first == pauseGamePopupMenuIndex) {
//this->setPaused(!paused);
//printf("popup paused = %d\n",paused);
bool allowAdminMenuItems = false;
NetworkRole role = networkManager.getNetworkRole();
if(role == nrServer) {
allowAdminMenuItems = true;
}
else if(role == nrClient) {
ClientInterface *clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
if(clientInterface != NULL &&
gameSettings.getMasterserver_admin() == clientInterface->getSessionKey()) {
allowAdminMenuItems = true;
}
}
if(allowAdminMenuItems) {
if(getPaused() == false) {
commander.tryPauseGame(false,false);
}
else {
commander.tryResumeGame(false,false);
}
}
}
else if(result.first == saveGamePopupMenuIndex){
saveGame();
}
//else if(result.first == markCellPopupMenuIndex) {
// startMarkCell();
//}
//else if(result.first == unmarkCellPopupMenuIndex) {
// isUnMarkCellEnabled = true;
//}
}
else if(popupMenuSwitchTeams.mouseClick(x, y)) {
//popupMenuSwitchTeams
std::pair<int,string> result = popupMenuSwitchTeams.mouseClickedMenuItem(x, y);
//printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first);
popupMenuSwitchTeams.setEnabled(false);
popupMenuSwitchTeams.setVisible(false);
//bool isNetworkGame = this->gameSettings.isNetworkGame();
int teamIndex = switchTeamIndexMap[result.first];
switch(teamIndex) {
case CREATE_NEW_TEAM:
{
int newTeam = getFirstUnusedTeamNumber();
//if(isNetworkGame == true) {
const Faction *faction = world.getThisFaction();
commander.trySwitchTeam(faction,newTeam);
//}
//else {
// const Faction *faction = world.getThisFaction();
// commander.trySwitchTeam(faction,newTeam);
//}
}
break;
case CANCEL_SWITCH_TEAM:
break;
default:
//if(isNetworkGame == true) {
const Faction *faction = world.getThisFaction();
commander.trySwitchTeam(faction,teamIndex);
//}
//else {
// const Faction *faction = world.getThisFaction();
// commander.trySwitchTeam(faction,teamIndex);
//}
break;
}
}
else if(popupMenuDisconnectPlayer.mouseClick(x, y)) {
//popupMenuSwitchTeams
std::pair<int,string> result = popupMenuDisconnectPlayer.mouseClickedMenuItem(x, y);
//printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first);
popupMenuDisconnectPlayer.setEnabled(false);
popupMenuDisconnectPlayer.setVisible(false);
//bool isNetworkGame = this->gameSettings.isNetworkGame();
//int playerIndex = disconnectPlayerIndexMap[result.first];
int factionIndex = disconnectPlayerIndexMap[result.first];
switch(factionIndex) {
case CANCEL_DISCONNECT_PLAYER:
break;
default:
// if(isNetworkGame == true) {
// const Faction *faction = world.getThisFaction();
// commander.trySwitchTeam(faction,teamIndex);
// }
// else {
// const Faction *faction = world.getThisFaction();
// commander.trySwitchTeam(faction,teamIndex);
// }
GameSettings *settings = world.getGameSettingsPtr();
Lang &lang= Lang::getInstance();
char szBuf[8096]="";
if(lang.hasString("DisconnectNetorkPlayerIndexConfirm") == true) {
snprintf(szBuf,8096,lang.getString("DisconnectNetorkPlayerIndexConfirm").c_str(),factionIndex+1,settings->getNetworkPlayerName(factionIndex).c_str());
}
else {
snprintf(szBuf,8096,"Confirm disconnection for player #%d - %s?",factionIndex+1,settings->getNetworkPlayerName(factionIndex).c_str());
}
disconnectPlayerConfirmMessageBox.setText(szBuf);
disconnectPlayerConfirmMessageBox.init(lang.getString("Yes"), lang.getString("No"));
disconnectPlayerConfirmMessageBox.setEnabled(true);
playerIndexDisconnect = world.getFaction(factionIndex)->getStartLocationIndex();
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
if(gameNetworkInterface != NULL) {
Lang &lang= Lang::getInstance();
const vector<string> languageList = settings->getUniqueNetworkPlayerLanguages();
for(unsigned int i = 0; i < (unsigned int)languageList.size(); ++i) {
char szMsg[8096]="";
if(lang.hasString("DisconnectNetorkPlayerIndexConfirmed",languageList[i]) == true) {
snprintf(szMsg,8096,lang.getString("DisconnectNetorkPlayerIndexConfirmed",languageList[i]).c_str(),factionIndex+1,settings->getNetworkPlayerName(factionIndex).c_str());
}
else {
snprintf(szMsg,8096,"Notice - Admin is warning to disconnect player #%d - %s!",factionIndex+1,settings->getNetworkPlayerName(factionIndex).c_str());
}
bool localEcho = lang.isLanguageLocal(languageList[i]);
gameNetworkInterface->sendTextMessage(szMsg,-1, localEcho,languageList[i]);
}
sleep(10);
}
break;
}
}
if(switchTeamConfirmMessageBox.getEnabled() == true) {
int button= -1;
if(switchTeamConfirmMessageBox.mouseClick(x,y,button)) {
switchTeamConfirmMessageBox.setEnabled(false);
SwitchTeamVote *vote = world.getThisFactionPtr()->getSwitchTeamVote(world.getThisFaction()->getCurrentSwitchTeamVoteFactionIndex());
vote->voted = true;
vote->allowSwitchTeam = (button == 0);
const Faction *faction = world.getThisFaction();
commander.trySwitchTeamVote(faction,vote);
}
}
else if(disconnectPlayerConfirmMessageBox.getEnabled() == true) {
int button= -1;
if(disconnectPlayerConfirmMessageBox.mouseClick(x,y,button)) {
disconnectPlayerConfirmMessageBox.setEnabled(false);
if(button == 0) {
const Faction *faction = world.getThisFaction();
commander.tryDisconnectNetworkPlayer(faction,playerIndexDisconnect);
}
}
}
//scrip message box, only if the exit box is not enabled
if( mainMessageBox.getEnabled() == false &&
errorMessageBox.getEnabled() == false &&
scriptManager.getMessageBox()->getEnabled()) {
int button= 0;
if(scriptManager.getMessageBox()->mouseClick(x, y, button)){
scriptManager.onMessageBoxOk();
messageBoxClick= true;
}
}
//minimap panel
if(messageBoxClick == false) {
if(metrics.isInMinimap(x, y)){
int xm= x - metrics.getMinimapX();
int ym= y - metrics.getMinimapY();
int xCell= static_cast<int>(xm * (static_cast<float>(map->getW()) / metrics.getMinimapW()));
int yCell= static_cast<int>(map->getH() - ym * (static_cast<float>(map->getH()) / metrics.getMinimapH()));
if(map->isInside(xCell, yCell) && map->isInsideSurface(map->toSurfCoords(Vec2i(xCell,yCell)))) {
if(gui.isSelectingPos()){
gui.mouseDownLeftGraphics(xCell, yCell, true);
}
else
{
if(!setMarker) {
cameraDragAllowed=true;
gameCamera.setPos(Vec2f(static_cast<float>(xCell), static_cast<float>(yCell)));
}
}
if(setMarker) {
Vec2i surfaceCellPos = map->toSurfCoords(Vec2i(xCell,yCell));
SurfaceCell *sc = map->getSurfaceCell(surfaceCellPos);
Vec3f vertex = sc->getVertex();
Vec2i targetPos(vertex.x,vertex.z);
MarkedCell mc(targetPos,world.getThisFaction(),"none",world.getThisFaction()->getStartLocationIndex());
addOrReplaceInHighlightedCells(mc);
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
gameNetworkInterface->sendHighlightCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex());
}
if(originalIsMarkCellEnabled == true && isMarkCellEnabled == true) {
Vec2i surfaceCellPos = map->toSurfCoords(Vec2i(xCell,yCell));
SurfaceCell *sc = map->getSurfaceCell(surfaceCellPos);
Vec3f vertex = sc->getVertex();
Vec2i targetPos(vertex.x,vertex.z);
MarkedCell mc(targetPos,world.getThisFaction(),"placeholder for note",world.getThisFaction()->getStartLocationIndex());
//GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
//gameNetworkInterface->sendMarkCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex(),mc.getNote());
//printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size());
isMarkCellEnabled = false;
cellMarkedData = mc;
cellMarkedPos = surfaceCellPos;
isMarkCellTextEnabled = true;
chatManager.switchOnEdit(this,500);
Renderer &renderer= Renderer::getInstance();
//renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos);
renderer.forceQuadCacheUpdate();
}
if(originalIsUnMarkCellEnabled == true && isUnMarkCellEnabled == true) {
Vec2i surfaceCellPos = map->toSurfCoords(Vec2i(xCell,yCell));
SurfaceCell *sc = map->getSurfaceCell(surfaceCellPos);
Vec3f vertex = sc->getVertex();
Vec2i targetPos(vertex.x,vertex.z);
// if(mapMarkedCellList.find(surfaceCellPos) != mapMarkedCellList.end()) {
// MarkedCell mc = mapMarkedCellList[surfaceCellPos];
// if(mc.getFaction() == world.getThisFaction()) {
// mapMarkedCellList.erase(surfaceCellPos);
// GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
// gameNetworkInterface->sendUnMarkCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex());
// }
// }
isUnMarkCellEnabled = false;
removeCellMarker(surfaceCellPos, world.getThisFaction());
//printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size());
Renderer &renderer= Renderer::getInstance();
//renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos);
renderer.forceQuadCacheUpdate();
}
}
}
//display panel
else if(metrics.isInDisplay(x, y) && !gui.isSelectingPos()) {
int xd= x - metrics.getDisplayX();
int yd= y - metrics.getDisplayY();
if(gui.mouseValid(xd, yd)) {
gui.mouseDownLeftDisplay(xd, yd);
}
else {
gui.mouseDownLeftGraphics(x, y, false);
}
}
//graphics panel
else {
gui.mouseDownLeftGraphics(x, y, false);
if(setMarker) {
Vec2i targetPos;
Vec2i screenPos(x,y-60);
targetPos=getMouseCellPos();
//Vec2i surfaceCellPos = map->toSurfCoords(targetPos);
MarkedCell mc(targetPos,world.getThisFaction(),"none",world.getThisFaction()->getStartLocationIndex());
addOrReplaceInHighlightedCells(mc);
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
gameNetworkInterface->sendHighlightCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex());
}
if(originalIsMarkCellEnabled == true && isMarkCellEnabled == true) {
Vec2i targetPos;
Vec2i screenPos(x,y-60);
targetPos=getMouseCellPos();
Vec2i surfaceCellPos = map->toSurfCoords(targetPos);
MarkedCell mc(targetPos,world.getThisFaction(),"placeholder for note",world.getThisFaction()->getStartLocationIndex());
//printf("#2 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size());
isMarkCellEnabled = false;
cellMarkedData = mc;
cellMarkedPos = surfaceCellPos;
isMarkCellTextEnabled = true;
chatManager.switchOnEdit(this,500);
//renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos);
Renderer::getInstance().forceQuadCacheUpdate();
}
if(originalIsUnMarkCellEnabled == true && isUnMarkCellEnabled == true) {
Vec2i targetPos;
Vec2i screenPos(x,y-35);
targetPos=getMouseCellPos();
Vec2i surfaceCellPos = map->toSurfCoords(targetPos);
// if(mapMarkedCellList.find(surfaceCellPos) != mapMarkedCellList.end()) {
// MarkedCell mc = mapMarkedCellList[surfaceCellPos];
// if(mc.getFaction() == world.getThisFaction()) {
// mapMarkedCellList.erase(surfaceCellPos);
// GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
// gameNetworkInterface->sendUnMarkCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex());
// }
// }
isUnMarkCellEnabled = false;
removeCellMarker(surfaceCellPos, world.getThisFaction());
//printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size());
//Renderer &renderer= Renderer::getInstance();
//renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos);
Renderer::getInstance().forceQuadCacheUpdate();
}
}
}
//exit message box, has to be the last thing to do in this function
if(errorMessageBox.getEnabled() == true) {
if(errorMessageBox.mouseClick(x, y)) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//close message box
errorMessageBox.setEnabled(false);
}
}
if(mainMessageBox.getEnabled()){
int button= 0;
if(mainMessageBox.mouseClick(x, y, button)) {
if(button==0) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(networkManager.getGameNetworkInterface() != NULL) {
networkManager.getGameNetworkInterface()->quitGame(true);
}
quitTriggeredIndicator = true;
return;
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//close message box
mainMessageBox.setEnabled(false);
}
}
}
}
catch(const exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
NetworkManager &networkManager= NetworkManager::getInstance();
if(networkManager.getGameNetworkInterface() != NULL) {
GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
networkInterface->sendTextMessage(szBuf,-1,true,"");
sleep(10);
networkManager.getGameNetworkInterface()->quitGame(true);
}
ErrorDisplayMessage(ex.what(),true);
}
}
void Game::mouseDownRight(int x, int y) {
if(this->masterserverMode == true) {
return;
}
if(currentUIState != NULL) {
currentUIState->mouseDownRight(x, y);
return;
}
try {
if(gameStarted == false || totalRenderFps <= 0) {
Logger::getInstance().handleMouseClick(x, y);
return;
}
Map *map= world.getMap();
const Metrics &metrics= Metrics::getInstance();
if(metrics.isInMinimap(x, y) ){
int xm= x - metrics.getMinimapX();
int ym= y - metrics.getMinimapY();
int xCell= static_cast<int>(xm * (static_cast<float>(map->getW()) / metrics.getMinimapW()));
int yCell= static_cast<int>(map->getH() - ym * (static_cast<float>(map->getH()) / metrics.getMinimapH()));
if(map->isInside(xCell, yCell) && map->isInsideSurface(map->toSurfCoords(Vec2i(xCell,yCell)))) {
gui.mouseDownRightGraphics(xCell, yCell,true);
}
}
else {
Vec2i targetPos;
Vec2i screenPos(x,y);
targetPos=getMouseCellPos();
if(isValidMouseCellPos() == true &&
map->isInsideSurface(map->toSurfCoords(targetPos)) == true) {
gui.mouseDownRightGraphics(x, y,false);
}
}
}
catch(const exception &ex) {
char szBuf[8096]="";
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);
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
NetworkManager &networkManager= NetworkManager::getInstance();
if(networkManager.getGameNetworkInterface() != NULL) {
GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
networkInterface->sendTextMessage(szBuf,-1,true,"");
sleep(10);
networkManager.getGameNetworkInterface()->quitGame(true);
}
ErrorDisplayMessage(ex.what(),true);
}
}
void Game::mouseUpCenter(int x, int y) {
if(this->masterserverMode == true) {
return;
}
if(gameStarted == false || totalRenderFps <= 0) {
return;
}
if(currentUIState != NULL) {
currentUIState->mouseUpCenter(x, y);
return;
}
if(mouseMoved == false) {
gameCamera.setState(GameCamera::sGame);
}
else {
mouseMoved = false;
}
}
void Game::mouseUpLeft(int x, int y) {
if(this->masterserverMode == true) {
return;
}
try {
if(gameStarted == false || totalRenderFps <= 0) {
return;
}
if(currentUIState != NULL) {
currentUIState->mouseUpLeft(x, y);
return;
}
gui.mouseUpLeftGraphics(x, y);
}
catch(const exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
NetworkManager &networkManager= NetworkManager::getInstance();
if(networkManager.getGameNetworkInterface() != NULL) {
GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
networkInterface->sendTextMessage(szBuf,-1,true,"");
sleep(10);
networkManager.getGameNetworkInterface()->quitGame(true);
}
ErrorDisplayMessage(ex.what(),true);
}
}
void Game::mouseDoubleClickLeft(int x, int y) {
if(this->masterserverMode == true) {
return;
}
try {
if(gameStarted == false || totalRenderFps <= 0) {
return;
}
if(currentUIState != NULL) {
currentUIState->mouseDoubleClickLeft(x, y);
return;
}
const Metrics &metrics= Metrics::getInstance();
if(metrics.isInMinimap(x, y)){
// no double click on minimap
}
else {
//display panel
if(metrics.isInDisplay(x, y) && !gui.isSelectingPos()) {
int xd= x - metrics.getDisplayX();
int yd= y - metrics.getDisplayY();
if(gui.mouseValid(xd, yd)){
return;
}
}
//graphics panel
gui.mouseDoubleClickLeftGraphics(x, y);
}
}
catch(const exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
NetworkManager &networkManager= NetworkManager::getInstance();
if(networkManager.getGameNetworkInterface() != NULL) {
GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
networkInterface->sendTextMessage(szBuf,-1,true,"");
sleep(10);
networkManager.getGameNetworkInterface()->quitGame(true);
}
ErrorDisplayMessage(ex.what(),true);
}
}
void Game::mouseMove(int x, int y, const MouseState *ms) {
if(this->masterserverMode == true) {
return;
}
try {
if(gameStarted == false || totalRenderFps <= 0) {
return;
}
if(currentUIState != NULL) {
currentUIState->mouseMove(x, y, ms);
return;
}
popupMenu.mouseMove(x, y);
popupMenuSwitchTeams.mouseMove(x, y);
popupMenuDisconnectPlayer.mouseMove(x, y);
const Metrics &metrics = Metrics::getInstance();
mouseX = x;
mouseY = y;
if (ms->get(mbCenter)) {
mouseMoved = true;
if(currentCameraFollowUnit == NULL) {
float ymult = 0.2f;
float xmult = 0.2f;
Vec2i oldPos = ::Shared::Platform::Window::getOldMousePos();
int oldx= (oldPos.x * metrics.getVirtualW() / metrics.getScreenW());
int oldy= ((metrics.getScreenH()-oldPos.y) * metrics.getVirtualH() / metrics.getScreenH());
lastMousePos.x=oldx;
lastMousePos.y=oldy;
gameCamera.transitionVH(-(y - oldy) * ymult, (oldx - x) * xmult);
}
mouseX=lastMousePos.x;
mouseY=lastMousePos.y;
::Shared::Platform::Window::revertMousePos();
return;
}
else if(currentCameraFollowUnit==NULL) {
//if(Window::isKeyDown() == false)
if(!camLeftButtonDown && !camRightButtonDown && !camUpButtonDown && !camDownButtonDown)
{
if(ms->get(mbLeft) && metrics.isInMinimap(x, y)) {
int xm= x - metrics.getMinimapX();
int ym= y - metrics.getMinimapY();
Map *map= world.getMap();
int xCell= static_cast<int>(xm * (static_cast<float>(map->getW()) / metrics.getMinimapW()));
int yCell= static_cast<int>(map->getH() - ym * (static_cast<float>(map->getH()) / metrics.getMinimapH()));
if(map->isInside(xCell, yCell) && map->isInsideSurface(map->toSurfCoords(Vec2i(xCell,yCell)))) {
if(gui.isSelectingPos()){
gui.mouseDownLeftGraphics(xCell, yCell, true);
}
else
{
if(cameraDragAllowed == true) {
gameCamera.setPos(Vec2f(static_cast<float>(xCell), static_cast<float>(yCell)));
}
}
}
}
else {
bool mouseMoveScrollsWorld = Config::getInstance().getBool("MouseMoveScrollsWorld","true");
if(mouseMoveScrollsWorld == true) {
if (y < 10) {
gameCamera.setMoveZ(-scrollSpeed);
}
else if (y > metrics.getVirtualH() - 10) {
gameCamera.setMoveZ(scrollSpeed);
}
else {
gameCamera.setMoveZ(0);
}
if (x < 10) {
gameCamera.setMoveX(-scrollSpeed);
}
else if (x > metrics.getVirtualW() - 10) {
gameCamera.setMoveX(scrollSpeed);
}
else {
gameCamera.setMoveX(0);
}
}
}
}
if(switchTeamConfirmMessageBox.getEnabled() == true) {
switchTeamConfirmMessageBox.mouseMove(x,y);
}
if(disconnectPlayerConfirmMessageBox.getEnabled() == true) {
disconnectPlayerConfirmMessageBox.mouseMove(x,y);
}
if (mainMessageBox.getEnabled()) {
mainMessageBox.mouseMove(x, y);
}
if (errorMessageBox.getEnabled()) {
errorMessageBox.mouseMove(x, y);
}
if (scriptManager.getMessageBox()->getEnabled()) {
scriptManager.getMessageBox()->mouseMove(x, y);
}
//else if (saveBox) {
// saveBox->mouseMove(x, y);
//} else {
// //graphics
gui.mouseMoveGraphics(x, y);
//}
}
//display
if ( !gui.isSelecting() && !gui.isSelectingPos()) {
if (!gui.isSelectingPos()) {
if(metrics.isInDisplay(x, y)){
gui.mouseMoveDisplay(x - metrics.getDisplayX(), y - metrics.getDisplayY());
}
else {
gui.mouseMoveOutsideDisplay();
}
}
}
lastMousePos.x = mouseX;
lastMousePos.y = mouseY;
Renderer &renderer= Renderer::getInstance();
renderer.ccomputePosition(Vec2i(mouseX, mouseY), mouseCellPos);
}
catch(const exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
NetworkManager &networkManager= NetworkManager::getInstance();
if(networkManager.getGameNetworkInterface() != NULL) {
GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
networkInterface->sendTextMessage(szBuf,-1,true,"");
sleep(10);
networkManager.getGameNetworkInterface()->quitGame(true);
}
ErrorDisplayMessage(ex.what(),true);
}
}
bool Game::isValidMouseCellPos() const{
if(world.getMap() == NULL){
return false;
}
else {
return world.getMap()->isInside(mouseCellPos);
}
}
void Game::eventMouseWheel(int x, int y, int zDelta) {
if(this->masterserverMode == true) {
return;
}
if(currentUIState != NULL) {
currentUIState->eventMouseWheel(x, y, zDelta);
return;
}
try {
gameCamera.zoom((float)zDelta / 60.0f);
}
catch(const exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
NetworkManager &networkManager= NetworkManager::getInstance();
if(networkManager.getGameNetworkInterface() != NULL) {
GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
networkInterface->sendTextMessage(szBuf,-1,true,"");
sleep(10);
networkManager.getGameNetworkInterface()->quitGame(true);
}
ErrorDisplayMessage(ex.what(),true);
}
}
void Game::startCameraFollowUnit() {
Selection *selection= gui.getSelectionPtr();
if(selection->getCount() == 1) {
Unit *currentUnit = selection->getUnitPtr(0);
if(currentUnit != NULL) {
currentCameraFollowUnit = currentUnit;
getGameCameraPtr()->setState(GameCamera::sUnit);
getGameCameraPtr()->setPos(currentCameraFollowUnit->getCurrMidHeightVector());
int rotation=currentCameraFollowUnit->getRotation();
getGameCameraPtr()->stop();
getGameCameraPtr()->rotateToVH(0.0f,(540-rotation)%360);
getGameCameraPtr()->setHAng((540-rotation)%360);
getGameCameraPtr()->setVAng(0.0f);
}
}
else {
if(currentCameraFollowUnit != NULL) {
currentCameraFollowUnit = NULL;
}
}
}
void Game::keyDown(SDL_KeyboardEvent key) {
if(this->masterserverMode == true) {
return;
}
try {
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);
if(gameStarted == false || totalRenderFps <= 0) {
return;
}
if(currentUIState != NULL) {
currentUIState->keyDown(key);
return;
}
Lang &lang= Lang::getInstance();
bool formerChatState=chatManager.getEditEnabled();
//send key to the chat manager
chatManager.keyDown(key);
if( formerChatState==false && chatManager.getEditEnabled()) {
camUpButtonDown= false;
camDownButtonDown = false;
camLeftButtonDown = false;
camRightButtonDown = false;
gameCamera.stopMove();
}
//printf("GAME KEYDOWN #1\n");
if(chatManager.getEditEnabled() == false) {
//printf("GAME KEYDOWN #2\n");
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);
Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
//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"));
//printf("SDL [%d] key [%d][%d]\n",configKeys.getSDLKey("SetMarker"),key.keysym.unicode,key.keysym.sym);
bool setMarkerKeyAllowsModifier = false;
if( configKeys.getSDLKey("SetMarker") == SDLK_RALT ||
configKeys.getSDLKey("SetMarker") == SDLK_LALT) {
setMarkerKeyAllowsModifier = true;
}
if(isKeyPressed(configKeys.getSDLKey("RenderInGamePerformance"),key, false) == true) {
renderInGamePerformance = !renderInGamePerformance;
Config::getInstance().setBool("PerformanceWarningEnabled",renderInGamePerformance, true);
}
//if(key == configKeys.getCharKey("RenderNetworkStatus")) {
else if(isKeyPressed(configKeys.getSDLKey("RenderNetworkStatus"),key, false) == true) {
renderNetworkStatus= !renderNetworkStatus;
}
//else if(key == configKeys.getCharKey("ShowFullConsole")) {
else if(isKeyPressed(configKeys.getSDLKey("ShowFullConsole"),key, false) == true) {
showFullConsole= true;
}
else if(isKeyPressed(configKeys.getSDLKey("SetMarker"),key, setMarkerKeyAllowsModifier) == true) {
setMarker= true;
}
//else if(key == configKeys.getCharKey("TogglePhotoMode")) {
else if(isKeyPressed(configKeys.getSDLKey("TogglePhotoMode"),key, false) == true) {
photoModeEnabled = !photoModeEnabled;
if( photoModeEnabled == true &&
this->gameSettings.isNetworkGame() == false) {
gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT);
}
else if(photoModeEnabled == false) {
gameCamera.setMaxHeight(-1);
}
}
//Toggle Healthbars
else if(isKeyPressed(configKeys.getSDLKey("ToggleHealthbars"),key, false) == true) {
switch (healthbarMode) {
case hbvUndefined:
healthbarMode=hbvOff;
console.addLine(lang.getString("Healthbar")+": "+lang.getString("HealthbarsOff"));
break;
case hbvOff:
healthbarMode=hbvAlways;
console.addLine(lang.getString("Healthbar")+": "+lang.getString("HealthbarsAlways"));
break;
case hbvAlways:
healthbarMode=hbvIfNeeded;
console.addLine(lang.getString("Healthbar")+": "+lang.getString("HealthbarsIfNeeded"));
break;
case hbvIfNeeded:
healthbarMode=hbvSelected;
console.addLine(lang.getString("Healthbar")+": "+lang.getString("HealthbarsSelected"));
break;
case hbvSelected:
healthbarMode=hbvSelected | hbvIfNeeded;
console.addLine(lang.getString("Healthbar")+": "+lang.getString("HealthbarsSelectedOrNeeded"));
break;
case (hbvSelected | hbvIfNeeded):
healthbarMode=hbvUndefined;
console.addLine(lang.getString("Healthbar")+": "+lang.getString("HealthbarsFactionDefault"));
break;
default:
printf("In [%s::%s Line: %d] Toggle Healthbars Hotkey - Invalid Value. Setting to default.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
healthbarMode=hbvUndefined;
break;
}
}
//Toggle music
//else if(key == configKeys.getCharKey("ToggleMusic")) {
else if(isKeyPressed(configKeys.getSDLKey("ToggleMusic"),key, false) == true) {
if(this->masterserverMode == false) {
Config &config = Config::getInstance();
StrSound *gameMusic = world.getThisFaction()->getType()->getMusic();
if(gameMusic != NULL) {
float configVolume = (config.getInt("SoundVolumeMusic") / 100.f);
float currentVolume = gameMusic->getVolume();
if(currentVolume > 0) {
gameMusic->setVolume(0);
console.addLine(lang.getString("GameMusic") + " " + lang.getString("Off"));
}
else {
//If the config says zero, use the default music volume
gameMusic->setVolume(configVolume ? configVolume : 0.9);
console.addLine(lang.getString("GameMusic"));
}
}
}
}
//move camera left
//else if(key == configKeys.getCharKey("CameraModeLeft")) {
else if(isKeyPressed(configKeys.getSDLKey("CameraModeLeft"),key, false) == true) {
gameCamera.setMoveX(-1);
camLeftButtonDown=true;
}
//move camera right
//else if(key == configKeys.getCharKey("CameraModeRight")) {
else if(isKeyPressed(configKeys.getSDLKey("CameraModeRight"),key, false) == true) {
gameCamera.setMoveX(1);
camRightButtonDown=true;
}
//move camera up
//else if(key == configKeys.getCharKey("CameraModeUp")) {
else if(isKeyPressed(configKeys.getSDLKey("CameraModeUp"),key, false) == true) {
gameCamera.setMoveZ(1);
camUpButtonDown=true;
}
//move camera down
//else if(key == configKeys.getCharKey("CameraModeDown")) {
else if(isKeyPressed(configKeys.getSDLKey("CameraModeDown"),key, false) == true) {
gameCamera.setMoveZ(-1);
camDownButtonDown=true;
}
//change camera mode
//else if(key == configKeys.getCharKey("FreeCameraMode")) {
else if(isKeyPressed(configKeys.getSDLKey("FreeCameraMode"),key, false) == true) {
if(gameCamera.getState()==GameCamera::sFree)
{
gameCamera.setState(GameCamera::sGame);
string stateString= gameCamera.getState()==GameCamera::sGame? lang.getString("GameCamera"): lang.getString("FreeCamera");
console.addLine(lang.getString("CameraModeSet")+" "+ stateString);
}
else if(gameCamera.getState()==GameCamera::sGame)
{
gameCamera.setState(GameCamera::sFree);
string stateString= gameCamera.getState()==GameCamera::sGame? lang.getString("GameCamera"): lang.getString("FreeCamera");
console.addLine(lang.getString("CameraModeSet")+" "+ stateString);
}
//else ignore!
}
//reset camera mode to normal
//else if(key == configKeys.getCharKey("ResetCameraMode")) {
else if(isKeyPressed(configKeys.getSDLKey("ResetCameraMode"),key, false) == true) {
if(currentCameraFollowUnit != NULL) {
currentCameraFollowUnit = NULL;
}
gameCamera.setState(GameCamera::sGame);
}
//pause
//else if(key == configKeys.getCharKey("PauseGame")) {
else if(isKeyPressed(configKeys.getSDLKey("PauseGame"),key, false) == true) {
//printf("Toggle pause paused = %d\n",paused);
//setPaused(!paused);
bool allowAdminMenuItems = false;
NetworkManager &networkManager= NetworkManager::getInstance();
NetworkRole role = networkManager.getNetworkRole();
if(role == nrServer) {
allowAdminMenuItems = true;
}
else if(role == nrClient) {
ClientInterface *clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
if(clientInterface != NULL &&
gameSettings.getMasterserver_admin() == clientInterface->getSessionKey()) {
allowAdminMenuItems = true;
}
}
if(allowAdminMenuItems) {
if(getPaused() == false) {
commander.tryPauseGame(false,false);
}
else {
commander.tryResumeGame(false,false);
}
}
}
else if(isKeyPressed(configKeys.getSDLKey("ExtraTeamColorMarker"),key, false) == true) {
//printf("Toggle ExtraTeamColorMarker\n");
toggleTeamColorMarker();
}
//switch display color
//else if(key == configKeys.getCharKey("ChangeFontColor")) {
else if(isKeyPressed(configKeys.getSDLKey("ChangeFontColor"),key, false) == true) {
gui.switchToNextDisplayColor();
}
//increment speed
//else if(key == configKeys.getCharKey("GameSpeedIncrease")) {
else if(isKeyPressed(configKeys.getSDLKey("GameSpeedIncrease"),key, false) == true) {
bool speedChangesAllowed= !NetworkManager::getInstance().isNetworkGameWithConnectedClients();
if(speedChangesAllowed){
incSpeed();
}
}
//decrement speed
//else if(key == configKeys.getCharKey("GameSpeedDecrease")) {
else if(isKeyPressed(configKeys.getSDLKey("GameSpeedDecrease"),key, false) == true) {
bool speedChangesAllowed= !NetworkManager::getInstance().isNetworkGameWithConnectedClients();
if(speedChangesAllowed){
decSpeed();
}
}
else if(isKeyPressed(configKeys.getSDLKey("BookmarkAdd"),key, false) == true) {
startMarkCell();
}
else if(isKeyPressed(configKeys.getSDLKey("BookmarkRemove"),key, false) == true) {
isUnMarkCellEnabled = true;
}
else if(isKeyPressed(configKeys.getSDLKey("CameraFollowSelectedUnit"),key, false) == true) {
startCameraFollowUnit();
}
//exit
else if(isKeyPressed(configKeys.getSDLKey("ExitKey"),key, false) == true) {
popupMenu.setEnabled(!popupMenu.getEnabled());
popupMenu.setVisible(popupMenu.getEnabled());
}
//group
else {
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);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("====== Check ingame custom grouping hotkeys ======\n");
//printf("====== Check ingame custom grouping hotkeys ======\n");
for(int idx = 1; idx <= Selection::maxGroups; idx++) {
string keyName = "GroupUnitsKey" + intToStr(idx);
//char groupHotKey = configKeys.getCharKey(keyName.c_str());
//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);
SDLKey groupHotKey = configKeys.getSDLKey(keyName.c_str());
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);
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));
//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));
//if(key == groupHotKey) {
if(isKeyPressed(groupHotKey,key) == true) {
//printf("GROUP KEY!\n");
//gui.groupKey(key-'0');
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
gui.groupKey(idx-1);
break;
}
}
}
//hotkeys
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());
if(gameCamera.getState() != GameCamera::sFree){
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);
gui.hotKey(key);
}
else {
//rotate camera leftt
//if(key == configKeys.getCharKey("CameraRotateLeft")) {
if(isKeyPressed(configKeys.getSDLKey("CameraRotateLeft"),key) == true) {
gameCamera.setRotate(-1);
}
//rotate camera right
//else if(key == configKeys.getCharKey("CameraRotateRight")){
else if(isKeyPressed(configKeys.getSDLKey("CameraRotateRight"),key) == true) {
gameCamera.setRotate(1);
}
//camera up
//else if(key == configKeys.getCharKey("CameraRotateUp")) {
else if(isKeyPressed(configKeys.getSDLKey("CameraRotateUp"),key) == true) {
gameCamera.setMoveY(1);
}
//camera down
//else if(key == configKeys.getCharKey("CameraRotateDown")) {
else if(isKeyPressed(configKeys.getSDLKey("CameraRotateDown"),key) == true) {
gameCamera.setMoveY(-1);
}
}
if(isKeyPressed(configKeys.getSDLKey("SaveGame"),key) == true) {
saveGame();
}
}
}
catch(const exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
NetworkManager &networkManager= NetworkManager::getInstance();
if(networkManager.getGameNetworkInterface() != NULL) {
GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
networkInterface->sendTextMessage(szBuf,-1,true,"");
sleep(10);
networkManager.getGameNetworkInterface()->quitGame(true);
}
ErrorDisplayMessage(ex.what(),true);
}
}
void Game::keyUp(SDL_KeyboardEvent key) {
if(this->masterserverMode == true) {
return;
}
try {
if(gameStarted == false || totalRenderFps <= 0) {
return;
}
if(currentUIState != NULL) {
currentUIState->keyUp(key);
return;
}
if(chatManager.getEditEnabled()) {
//send key to the chat manager
chatManager.keyUp(key);
}
else {
Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
//if(key == configKeys.getCharKey("ShowFullConsole")) {
if(isKeyPressed(configKeys.getSDLKey("ShowFullConsole"),key) == true) {
showFullConsole= false;
}
else if(isKeyPressed(configKeys.getSDLKey("SetMarker"),key) == true) {
setMarker= false;
}
//else if(key == configKeys.getCharKey("CameraRotateLeft") ||
// key == configKeys.getCharKey("CameraRotateRight")) {
else if(isKeyPressed(configKeys.getSDLKey("CameraRotateLeft"),key) == true ||
isKeyPressed(configKeys.getSDLKey("CameraRotateRight"),key) == true) {
gameCamera.setRotate(0);
}
//else if(key == configKeys.getCharKey("CameraRotateDown") ||
// key == configKeys.getCharKey("CameraRotateUp")) {
else if(isKeyPressed(configKeys.getSDLKey("CameraRotateDown"),key) == true ||
isKeyPressed(configKeys.getSDLKey("CameraRotateUp"),key) == true) {
gameCamera.setMoveY(0);
}
//else if(key == configKeys.getCharKey("CameraModeUp")){
else if(isKeyPressed(configKeys.getSDLKey("CameraModeUp"),key) == true) {
gameCamera.setMoveZ(0);
camUpButtonDown= false;
calcCameraMoveZ();
}
//else if(key == configKeys.getCharKey("CameraModeDown")){
else if(isKeyPressed(configKeys.getSDLKey("CameraModeDown"),key) == true) {
gameCamera.setMoveZ(0);
camDownButtonDown= false;
calcCameraMoveZ();
}
//else if(key == configKeys.getCharKey("CameraModeLeft")){
else if(isKeyPressed(configKeys.getSDLKey("CameraModeLeft"),key) == true) {
gameCamera.setMoveX(0);
camLeftButtonDown= false;
calcCameraMoveX();
}
//else if(key == configKeys.getCharKey("CameraModeRight")){
else if(isKeyPressed(configKeys.getSDLKey("CameraModeRight"),key) == true) {
gameCamera.setMoveX(0);
camRightButtonDown= false;
calcCameraMoveX();
}
}
}
catch(const exception &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
NetworkManager &networkManager= NetworkManager::getInstance();
if(networkManager.getGameNetworkInterface() != NULL) {
GameNetworkInterface *networkInterface = NetworkManager::getInstance().getGameNetworkInterface();
networkInterface->sendTextMessage(szBuf,-1,true,"");
sleep(10);
networkManager.getGameNetworkInterface()->quitGame(true);
}
ErrorDisplayMessage(ex.what(),true);
}
}
void Game::calcCameraMoveX(){
//move camera left
if(camLeftButtonDown == true){
gameCamera.setMoveX(-1);
}
//move camera right
else if(camRightButtonDown == true){
gameCamera.setMoveX(1);
}
}
void Game::calcCameraMoveZ(){
//move camera up
if(camUpButtonDown == true){
gameCamera.setMoveZ(1);
}
//move camera down
else if(camDownButtonDown == true){
gameCamera.setMoveZ(-1);
}
}
void Game::keyPress(SDL_KeyboardEvent c) {
if(this->masterserverMode == true) {
return;
}
if(gameStarted == false || totalRenderFps <= 0) {
return;
}
if(currentUIState != NULL) {
currentUIState->keyPress(c);
return;
}
chatManager.keyPress(c);
}
Stats Game::getEndGameStats() {
Stats endStats;
endStats = *(world.getStats());
//NetworkManager &networkManager= NetworkManager::getInstance();
if (this->masterserverMode == true) {
endStats.setIsMasterserverMode(true);
}
return endStats;
}
Stats Game::quitGame() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(quitGameCalled == true) {
Stats endStats = getEndGameStats();
return endStats;
}
quitGameCalled = true;
NetworkManager &networkManager= NetworkManager::getInstance();
NetworkRole role = networkManager.getNetworkRole();
string suffix = "_client";
if(role == nrServer) {
suffix = "_server";
}
this->DumpCRCWorldLogIfRequired(suffix);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled == true) {
world.DumpWorldToLog();
}
//printf("Check savegame\n");
//printf("Saving...\n");
if(Config::getInstance().getBool("AutoTest")){
this->saveGame(GameConstants::saveGameFileAutoTestDefault);
}
Stats endStats = getEndGameStats();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//printf("In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
NetworkManager::getInstance().end();
//sleep(0);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
return endStats;
}
void Game::DumpCRCWorldLogIfRequired(string fileSuffix) {
bool isNetworkGame = this->gameSettings.isNetworkGame();
if(isNetworkGame == true) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Check save world CRC to log. isNetworkGame = %d fileSuffix = %s\n",isNetworkGame,fileSuffix.c_str());
GameSettings *settings = world.getGameSettingsPtr();
if(settings != NULL &&
(isFlagType1BitEnabled(ft1_network_synch_checks_verbose) == true ||
isFlagType1BitEnabled(ft1_network_synch_checks) == true)) {
string debugCRCWorldLogFile = Config::getInstance().getString("DebugCRCWorldLogFile","debugCRCWorld.log");
debugCRCWorldLogFile += fileSuffix;
if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
debugCRCWorldLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugCRCWorldLogFile;
}
else {
string userData = Config::getInstance().getString("UserData_Root","");
if(userData != "") {
endPathWithSlash(userData);
}
debugCRCWorldLogFile = userData + debugCRCWorldLogFile;
}
printf("Save to log debugCRCWorldLogFile = %s\n",debugCRCWorldLogFile.c_str());
#if defined(WIN32) && !defined(__MINGW32__)
FILE *fp = _wfopen(utf8_decode(debugCRCWorldLogFile).c_str(), L"w");
std::ofstream logFile(fp);
#else
std::ofstream logFile;
logFile.open(debugCRCWorldLogFile.c_str(), ios_base::out | ios_base::trunc);
#endif
logFile << "World CRC debug information:" << std::endl;
logFile << "============================" << std::endl;
logFile << "Software version: " << glestVersionString << "-" << getCompilerNameString() << "-" << getGITRevisionString() << std::endl;
logFile << "Maximum framecount: " << world.getFaction(0)->getCRC_DetailsForWorldFrameCount() << std::endl;
for(unsigned int worldFrameIndex = 0; worldFrameIndex < world.getFaction(0)->getCRC_DetailsForWorldFrameCount(); ++worldFrameIndex) {
//factions (and their related info)
for(int i = 0; i < world.getFactionCount(); ++i) {
logFile << "Faction detail for index: " << i << std::endl;
logFile << "--------------------------" << std::endl;
std::pair<int,string> details = world.getFaction(i)->getCRC_DetailsForWorldFrameIndex(worldFrameIndex);
logFile << string("** world frame: ") << details.first << std::endl;
logFile << details.second << std::endl;
}
}
logFile.close();
#if defined(WIN32) && !defined(__MINGW32__)
if(fp) {
fclose(fp);
}
#endif
}
}
}
void Game::exitGameState(Program *program, Stats &endStats) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
Game *game = dynamic_cast<Game *>(program->getState());
//printf("game = %p\n",game);
if(game) {
game->setEndGameTeamWinnersAndLosers();
game->endGame();
}
if((game != NULL && game->isMasterserverMode() == true) ||
Config::getInstance().getBool("AutoTest") == true) {
printf("Game ending with stats:\n");
printf("-----------------------\n");
string gameStats = endStats.getStats();
printf("%s",gameStats.c_str());
printf("-----------------------\n");
}
ProgramState *newState = new BattleEnd(program, &endStats, game);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
program->setState(newState, false);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
}
// ==================== PRIVATE ====================
void Game::highlightUnit(int unitId,float radius, float thickness, Vec4f color) {
HighlightSpecialUnitInfo info;
info.radius = radius;
info.thickness = thickness;
info.color = color;
unitHighlightList[unitId] = info;
}
void Game::unhighlightUnit(int unitId) {
if(unitHighlightList.find(unitId) != unitHighlightList.end()) {
unitHighlightList.erase(unitId);
}
}
// ==================== render ====================
void Game::render3d(){
Chrono chrono;
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
Renderer &renderer= Renderer::getInstance();
//init
renderer.reset3d();
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
// renderer.computeVisibleQuad();
// 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());
// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
renderer.loadGameCameraMatrix();
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
renderer.computeVisibleQuad();
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
renderer.setupLighting();
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
//shadow map
renderer.renderShadowsToTexture(avgRenderFps);
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
//clear buffers
renderer.clearBuffers();
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
//surface
renderer.renderSurface(avgRenderFps);
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
//selection circles
renderer.renderSelectionEffects(healthbarMode);
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
// renderTeamColorCircle
if((renderExtraTeamColor&renderTeamColorCircleBit)>0){
renderer.renderTeamColorCircle();
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
}
renderer.renderSpecialHighlightUnits(unitHighlightList);
// renderTeamColorCircle
renderer.renderMorphEffects();
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
//objects
renderer.renderObjects(avgRenderFps);
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
//ground units
renderer.renderUnits(false, avgRenderFps);
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
// renderTeamColorPlane
if((renderExtraTeamColor&renderTeamColorPlaneBit)>0){
renderer.renderTeamColorPlane();
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
}
//water
renderer.renderWater();
renderer.renderWaterEffects();
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
//air units
renderer.renderUnits(true, avgRenderFps);
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
//particles
renderer.renderParticleManager(rsGame);
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
//renderOnTopBars (aka Healthbars)
if(photoModeEnabled == false) {
renderer.renderHealthBars(healthbarMode);
}
//mouse 3d
renderer.renderMouse3d();
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());
renderer.renderUnitsToBuild(avgRenderFps);
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());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
renderer.setLastRenderFps(lastRenderFps);
}
void Game::updateWorldStats() {
world.getStats()->setWorldTimeElapsed(world.getTimeFlow()->getTime());
if(difftime((long int)time(NULL),lastMaxUnitCalcTime) >= 1) {
lastMaxUnitCalcTime = time(NULL);
int totalUnitcount = 0;
for(int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction= world.getFaction(i);
totalUnitcount += faction->getUnitCount();
}
if(world.getStats()->getMaxConcurrentUnitCount() < totalUnitcount) {
world.getStats()->setMaxConcurrentUnitCount(totalUnitcount);
}
world.getStats()->setTotalEndGameConcurrentUnitCount(totalUnitcount);
world.getStats()->setFramesPlayed(world.getFrameCount());
}
}
string Game::getDebugStats(std::map<int,string> &factionDebugInfo) {
string str = "";
if(this->masterserverMode == false) {
str+= "MouseXY: " + intToStr(mouseX) + "," + intToStr(mouseY)+"\n";
if(world.getMap()->isInsideSurface(world.getMap()->toSurfCoords(mouseCellPos)) == true) {
str+= "MouseXY cell coords: " + intToStr(mouseCellPos.x) + "," + intToStr(mouseCellPos.y)+"\n";
}
str+= "PosObjWord: " + intToStr(gui.getPosObjWorld().x) + "," + intToStr(gui.getPosObjWorld().y)+"\n";
}
str+= "Render FPS: " + intToStr(lastRenderFps) + "[" + intToStr(avgRenderFps) + "]\n";
str+= "Update FPS: " + intToStr(lastUpdateFps) + "[" + intToStr(avgUpdateFps) + "]\n";
if(this->masterserverMode == false) {
str+= "GameCamera pos: " + floatToStr(gameCamera.getPos().x)+","+floatToStr(gameCamera.getPos().y)+","+floatToStr(gameCamera.getPos().z)+"\n";
//str+= "Cached surfacedata: " + intToStr(renderer.getCachedSurfaceDataSize())+"\n";
}
//intToStr(stats.getFramesToCalculatePlaytime()/GameConstants::updateFps/60
str+= "Time: " + floatToStr(world.getTimeFlow()->getTime(),2) + " [" + floatToStr((double)world.getStats()->getFramesToCalculatePlaytime() / (float)GameConstants::updateFps / 60.0,2) + "]\n";
if(SystemFlags::getThreadedLoggerRunning() == true) {
str+= "Log buffer count: " + intToStr(SystemFlags::getLogEntryBufferCount())+"\n";
}
str+= "UnitRangeCellsLookupItemCache: " + world.getUnitUpdater()->getUnitRangeCellsLookupItemCacheStats()+"\n";
str+= "ExploredCellsLookupItemCache: " + world.getExploredCellsLookupItemCacheStats()+"\n";
str+= "FowAlphaCellsLookupItemCache: " + world.getFowAlphaCellsLookupItemCacheStats()+"\n";
const string selectionType = toLower(Config::getInstance().getString("SelectionType",Config::colorPicking));
str += "Selection type: " + toLower(selectionType) + "\n";
if(selectionType == Config::colorPicking) {
str += "Color picking used color list size: " + intToStr(BaseColorPickEntity::getUsedColorIDListSize()) +"\n";
}
//str+= "AllFactionsCacheStats: " + world.getAllFactionsCacheStats()+"\n";
//str+= "AttackWarningCount: " + intToStr(world.getUnitUpdater()->getAttackWarningCount()) + "\n";
str+= "Map: " + gameSettings.getMap() +"\n";
str+= "Tileset: " + gameSettings.getTileset() +"\n";
str+= "Techtree: " + gameSettings.getTech() +"\n";
if(this->masterserverMode == false) {
Renderer &renderer= Renderer::getInstance();
str+= "Triangle count: " + intToStr(renderer.getTriangleCount())+"\n";
str+= "Vertex count: " + intToStr(renderer.getPointCount())+"\n";
}
str+= "Frame count:" + intToStr(world.getFrameCount())+"\n";
//visible quad
if(this->masterserverMode == false) {
Renderer &renderer= Renderer::getInstance();
Quad2i visibleQuad= renderer.getVisibleQuad();
//Quad2i visibleQuadCamera= renderer.getVisibleQuadFromCamera();
str+= "Visible quad: ";
for(int i= 0; i<4; ++i){
str+= "(" + intToStr(visibleQuad.p[i].x) + "," +intToStr(visibleQuad.p[i].y) + ") ";
}
// str+= "\n";
// str+= "Visible quad camera: ";
// for(int i= 0; i<4; ++i){
// str+= "(" + intToStr(visibleQuadCamera.p[i].x) + "," +intToStr(visibleQuadCamera.p[i].y) + ") ";
// }
str+= "\n";
str+= "Visible quad area: " + floatToStr(visibleQuad.area()) +"\n";
// str+= "Visible quad camera area: " + floatToStr(visibleQuadCamera.area()) +"\n";
// Rect2i boundingRect= visibleQuad.computeBoundingRect();
// Rect2i scaledRect= boundingRect/Map::cellScale;
// scaledRect.clamp(0, 0, world.getMap()->getSurfaceW()-1, world.getMap()->getSurfaceH()-1);
// renderer.renderText3D("#1", coreData.getMenuFontNormal3D(), Vec3f(1.0f), scaledRect.p[0].x, scaledRect.p[0].y, false);
// renderer.renderText3D("#2", coreData.getMenuFontNormal3D(), Vec3f(1.0f), scaledRect.p[1].x, scaledRect.p[1].y, false);
}
int totalUnitcount = 0;
for(int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction= world.getFaction(i);
totalUnitcount += faction->getUnitCount();
}
if(this->masterserverMode == false) {
Renderer &renderer= Renderer::getInstance();
VisibleQuadContainerCache &qCache =renderer.getQuadCache();
int visibleUnitCount = (int)qCache.visibleQuadUnitList.size();
str+= "Visible unit count: " + intToStr(visibleUnitCount) + " total: " + intToStr(totalUnitcount) + "\n";
int visibleObjectCount = (int)qCache.visibleObjectList.size();
str+= "Visible object count: " + intToStr(visibleObjectCount) +"\n";
}
else {
str+= "Total unit count: " + intToStr(totalUnitcount) + "\n";
}
// resources
for(int i = 0; i < world.getFactionCount(); ++i) {
string factionInfo = this->gameSettings.getNetworkPlayerName(i);
//factionInfo += " [" + this->gameSettings.getNetworkPlayerUUID(i) + "]";
float multi=world.getStats()->getResourceMultiplier(i);
string multiplier="["+floatToStr(multi,1)+"]";
switch(this->gameSettings.getFactionControl(i)) {
case ctCpuEasy:
factionInfo += " CPU Easy"+multiplier;
break;
case ctCpu:
factionInfo += " CPU Normal"+multiplier;
break;
case ctCpuUltra:
factionInfo += " CPU Ultra"+multiplier;
break;
case ctCpuMega:
factionInfo += " CPU Mega"+multiplier;
break;
}
factionInfo += " [" + formatString(this->gameSettings.getFactionTypeName(i)) +
" team: " + intToStr(this->gameSettings.getTeam(i)) + "]";
// bool showResourceDebugInfo = true;
// if(showResourceDebugInfo == true) {
// factionInfo +=" res: ";
// for(int j = 0; j < world.getTechTree()->getResourceTypeCount(); ++j) {
// factionInfo += world.getFaction(i)->getResource(j)->getType()->getName()+":"+intToStr(world.getFaction(i)->getResource(j)->getAmount());
// factionInfo += " ";
// }
// }
factionDebugInfo[i] = factionInfo;
}
return str;
}
void Game::render2d() {
Renderer &renderer= Renderer::getInstance();
//Config &config= Config::getInstance();
CoreData &coreData= CoreData::getInstance();
//init
renderer.reset2d();
//HUD
if(visibleHUD == true && photoModeEnabled == false) {
renderer.renderHud();
}
//display
renderer.renderDisplay();
//minimap
if(photoModeEnabled == false) {
renderer.renderMinimap();
}
renderer.renderVisibleMarkedCells();
renderer.renderVisibleMarkedCells(true,lastMousePos.x,lastMousePos.y);
//selection
renderer.renderSelectionQuad();
//highlighted Cells
renderer.renderHighlightedCellsOnMinimap();
if(switchTeamConfirmMessageBox.getEnabled() == true) {
renderer.renderMessageBox(&switchTeamConfirmMessageBox);
}
if(disconnectPlayerConfirmMessageBox.getEnabled() == true) {
renderer.renderMessageBox(&disconnectPlayerConfirmMessageBox);
}
//exit message box
if(errorMessageBox.getEnabled()) {
renderer.renderMessageBox(&errorMessageBox);
}
if(mainMessageBox.getEnabled()) {
renderer.renderMessageBox(&mainMessageBox);
}
//script message box
if( mainMessageBox.getEnabled() == false &&
errorMessageBox.getEnabled() == false &&
scriptManager.getMessageBoxEnabled()) {
renderer.renderMessageBox(scriptManager.getMessageBox());
}
//script display text
if(!scriptManager.getDisplayText().empty() && !scriptManager.getMessageBoxEnabled()){
Vec4f fontColor = getGui()->getDisplay()->getColor();
if(Renderer::renderText3DEnabled == true) {
renderer.renderText3D(
scriptManager.getDisplayText(), coreData.getMenuFontNormal3D(),
Vec3f(fontColor.x,fontColor.y,fontColor.z), 200, 660, false);
}
else {
renderer.renderText(
scriptManager.getDisplayText(), coreData.getMenuFontNormal(),
Vec3f(fontColor.x,fontColor.y,fontColor.z), 200, 660, false);
}
}
renderVideoPlayer();
renderer.renderPopupMenu(&popupMenu);
renderer.renderPopupMenu(&popupMenuSwitchTeams);
renderer.renderPopupMenu(&popupMenuDisconnectPlayer);
if(program != NULL) program->renderProgramMsgBox();
renderer.renderChatManager(&chatManager);
//debug info
bool perfLogging = false;
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true ||
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
perfLogging = true;
}
string str="";
std::map<int,string> factionDebugInfo;
if( renderer.getShowDebugUI() == true ||
(perfLogging == true && difftime((long int)time(NULL),lastRenderLog2d) >= 1)) {
str = getDebugStats(factionDebugInfo);
}
if(this->getRenderInGamePerformance() == true) {
renderer.renderPerformanceStats();
}
else {
static time_t lastGamePerfCheck = time(NULL);
if(difftime((long int)time(NULL),lastGamePerfCheck) > 3) {
lastGamePerfCheck = time(NULL);
getGamePerformanceCounts(true);
}
}
if(renderer.getShowDebugUI() == true) {
const Metrics &metrics= Metrics::getInstance();
int mh= metrics.getMinimapH();
if(this->getRenderInGamePerformance() == true) {
mh = mh + ((int)gamePerformanceCounts.size() * 14);
}
const Vec4f fontColor=getGui()->getDisplay()->getColor();
if(Renderer::renderText3DEnabled == true) {
renderer.renderTextShadow3D(str, coreData.getMenuFontNormal3D(),
fontColor, 10, metrics.getVirtualH() - mh - 60, false);
}
else {
renderer.renderTextShadow(str, coreData.getMenuFontNormal(),
fontColor, 10, metrics.getVirtualH() - mh - 60, false);
}
vector<string> lineTokens;
Tokenize(str,lineTokens,"\n");
int fontHeightNormal = (Renderer::renderText3DEnabled == true ? coreData.getMenuFontNormal3D()->getMetrics()->getHeight("W") : coreData.getMenuFontNormal()->getMetrics()->getHeight("W"));
int fontHeightBig = (Renderer::renderText3DEnabled == true ? coreData.getMenuFontBig3D()->getMetrics()->getHeight("W") : coreData.getMenuFontBig()->getMetrics()->getHeight("W"));
int playerPosY = (int)lineTokens.size() * fontHeightNormal;
//printf("lineTokens.size() = %d\n",lineTokens.size());
for(int i = 0; i < world.getFactionCount(); ++i) {
string factionInfo = factionDebugInfo[i];
Vec3f playerColor = world.getFaction(i)->getTexture()->getPixmapConst()->getPixel3f(0, 0);
if(Renderer::renderText3DEnabled == true) {
renderer.renderText3D(factionInfo, coreData.getMenuFontBig3D(),
Vec4f(playerColor.x,playerColor.y,playerColor.z,1.0),
10,
//metrics.getVirtualH() - mh - 90 - 280 - (i * 16),
metrics.getVirtualH() - mh - 60 - playerPosY - fontHeightBig - (fontHeightBig * i),
false);
}
else {
renderer.renderText(factionInfo, coreData.getMenuFontBig(),
Vec4f(playerColor.x,playerColor.y,playerColor.z,1.0),
10,
//metrics.getVirtualH() - mh - 90 - 280 - (i * 16),
metrics.getVirtualH() - mh - 60 - playerPosY - fontHeightBig - (fontHeightBig * i),
false);
}
}
if((renderer.getShowDebugUILevel() & debugui_unit_titles) == debugui_unit_titles) {
if(renderer.getAllowRenderUnitTitles() == false) {
renderer.setAllowRenderUnitTitles(true);
}
if(Renderer::renderText3DEnabled == true) {
renderer.renderUnitTitles3D(coreData.getMenuFontNormal3D(),Vec3f(1.0f));
}
else {
renderer.renderUnitTitles(coreData.getMenuFontNormal(),Vec3f(1.0f));
}
}
}
//network status
if(renderNetworkStatus == true) {
if(NetworkManager::getInstance().getGameNetworkInterface() != NULL) {
const Metrics &metrics= Metrics::getInstance();
int mx= metrics.getMinimapX();
//int my= metrics.getMinimapY();
int mw= metrics.getMinimapW();
//int mh= metrics.getMinimapH();
const Vec4f fontColor=getGui()->getDisplay()->getColor();
if(Renderer::renderText3DEnabled == true) {
renderer.renderTextShadow3D(
NetworkManager::getInstance().getGameNetworkInterface()->getNetworkStatus(),
coreData.getMenuFontNormal3D(),
fontColor, mx + mw + 5 , metrics.getVirtualH()-30-20, false);
}
else {
renderer.renderTextShadow(
NetworkManager::getInstance().getGameNetworkInterface()->getNetworkStatus(),
coreData.getMenuFontNormal(),
fontColor, mx + mw + 5 , metrics.getVirtualH()-30-20, false);
}
}
}
// clock
if(photoModeEnabled == false && timeDisplay == true) {
renderer.renderClock();
}
//resource info
if(photoModeEnabled == false) {
if(this->masterserverMode == false) {
renderer.renderResourceStatus();
}
renderer.renderConsole(&console,showFullConsole?consoleFull:consoleNormal);
}
//2d mouse
renderer.renderMouse2d(mouseX, mouseY, mouse2d, gui.isSelectingPos()? 1.f: 0.f);
if(perfLogging == true && difftime((long int)time(NULL),lastRenderLog2d) >= 1) {
lastRenderLog2d = time(NULL);
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());
}
}
// ==================== misc ====================
void Game::checkWinner() {
// lookup int is team #, value is players alive on team
std::map<int, int> teamsAlive = getTeamsAlive();
if(gameOver == false || teamsAlive.size() > 1) {
if(gameSettings.getDefaultVictoryConditions()) {
checkWinnerStandard();
}
else {
checkWinnerScripted();
}
}
}
void Game::setEndGameTeamWinnersAndLosers() {
//bool lose= false;
bool checkTeamIndex = !(this->masterserverMode == false && world.getThisFaction()->getPersonalityType() != fpt_Observer);
// lookup int is team #, value is players alive on team
std::map<int,int> teamsAlive;
for(int i = 0; i < world.getFactionCount(); ++i) {
if(checkTeamIndex == false || i != world.getThisFactionIndex()) {
if(factionLostGame(world.getFaction(i)) == false) {
teamsAlive[world.getFaction(i)->getTeam()] = teamsAlive[world.getFaction(i)->getTeam()] + 1;
}
}
}
// did some team win
if(teamsAlive.size() <= 1) {
for(int i=0; i< world.getFactionCount(); ++i) {
if(checkTeamIndex == false || i != world.getThisFactionIndex()) {
if(teamsAlive.find(world.getFaction(i)->getTeam()) != teamsAlive.end()) {
world.getStats()->setVictorious(i);
}
else if(i == world.getThisFactionIndex()) {
//lose= true;
}
}
}
bool firstGameOverTrigger = false;
if(gameOver == false) {
firstGameOverTrigger = true;
gameOver= true;
}
if( this->gameSettings.isNetworkGame() == false ||
this->gameSettings.getEnableObserverModeAtEndGame() == true) {
// Let the happy winner view everything left in the world
// This caused too much LAG for network games
if(this->gameSettings.isNetworkGame() == false) {
Renderer::getInstance().setPhotoMode(true);
gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT);
}
// END
}
if(firstGameOverTrigger == true) {
scriptManager.onGameOver(true);
}
if(world.getFactionCount() == 1 && world.getFaction(0)->getPersonalityType() == fpt_Observer) {
//printf("!!!!!!!!!!!!!!!!!!!!");
//gameCamera.setMoveY(100.0);
gameCamera.zoom(-300);
//gameCamera.update();
}
// else {
// if(lose == true) {
// showLoseMessageBox();
// }
// else {
// showWinMessageBox();
// }
// }
}
}
std::map<int, int> Game::getTeamsAlive() {
std::map<int, int> teamsAlive;
for (int factionIndex = 0; factionIndex < world.getFactionCount(); ++factionIndex) {
if (factionIndex != world.getThisFactionIndex()) {
if (factionLostGame(world.getFaction(factionIndex)) == false) {
teamsAlive[world.getFaction(factionIndex)->getTeam()] =
teamsAlive[world.getFaction(factionIndex)->getTeam()] + 1;
}
}
}
// did some team win
return teamsAlive;
}
void Game::checkWinnerStandardHeadlessOrObserver() {
// lookup int is team #, value is players alive on team
std::map<int, int> teamsAlive = getTeamsAlive();
// did some team win
if (teamsAlive.size() <= 1) {
if (this->masterserverMode == true) {
printf("Game finished...\n");
}
for (int factionIndex = 0; factionIndex < world.getFactionCount(); ++factionIndex) {
Faction* faction = world.getFaction(factionIndex);
if (factionIndex != world.getThisFactionIndex() &&
teamsAlive.find(faction->getTeam()) != teamsAlive.end()) {
world.getStats()->setVictorious(factionIndex);
if (this->masterserverMode == true) {
printf("Player: %s is on the winning team #: %d\n",
this->gameSettings.getNetworkPlayerName(factionIndex).c_str(),
faction->getTeam());
}
}
}
bool wasGameOverAlready = gameOver;
gameOver = true;
// Only need to process this once
if(wasGameOverAlready == false) {
if (this->gameSettings.isNetworkGame() == false ||
this->gameSettings.getEnableObserverModeAtEndGame() == true) {
// Let the happy winner view everything left in the world
// This caused too much LAG for network games
if (this->gameSettings.isNetworkGame() == false) {
Renderer::getInstance().setPhotoMode(true);
gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT);
}
// END
}
scriptManager.onGameOver(true);
if (world.getFactionCount() == 1 &&
world.getFaction(0)->getPersonalityType() == fpt_Observer) {
gameCamera.zoom(-300);
}
else {
showWinMessageBox();
}
}
}
}
void Game::checkWinnerStandardPlayer() {
//lose
bool lose = false;
if (factionLostGame(world.getThisFaction()) == true) {
bool playerLostGame = true;
// Team Shared units enabled?
if(isFlagType1BitEnabled(ft1_allow_shared_team_units) == true) {
// Check if all team members have lost?
for (int factionIndex = 0; factionIndex < world.getFactionCount(); ++factionIndex) {
if (world.getFaction(factionIndex)->getPersonalityType() != fpt_Observer) {
if (world.getFaction(factionIndex)->isAlly(world.getThisFaction()) == true &&
factionLostGame(world.getFaction(factionIndex)) == false) {
playerLostGame = false;
break;
}
}
}
}
if(playerLostGame == true) {
lose = true;
for (int factionIndex = 0; factionIndex < world.getFactionCount(); ++factionIndex) {
if (world.getFaction(factionIndex)->getPersonalityType() != fpt_Observer) {
if (world.getFaction(factionIndex)->isAlly(world.getThisFaction()) == false &&
factionLostGame(world.getFaction(factionIndex)) == false) {
world.getStats()->setVictorious(factionIndex);
}
}
}
bool wasGameOverAlready = gameOver;
gameOver = true;
// Only need to process losing once
if(wasGameOverAlready == false) {
if (this->gameSettings.isNetworkGame() == false ||
this->gameSettings.getEnableObserverModeAtEndGame()
== true) {
// Let the poor user watch everything unfold
// This caused too much LAG for network games
if (this->gameSettings.isNetworkGame() == false) {
Renderer::getInstance().setPhotoMode(true);
gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT);
}
// END
// but don't let him cheat via teamchat
chatManager.setDisableTeamMode(true);
}
scriptManager.onGameOver(!lose);
showLoseMessageBox();
}
}
}
//win
if (lose == false) {
bool win = true;
for (int factionIndex = 0; factionIndex < world.getFactionCount(); ++factionIndex) {
if (factionIndex != world.getThisFactionIndex()) {
if (world.getFaction(factionIndex)->getPersonalityType() != fpt_Observer) {
if (factionLostGame(world.getFaction(factionIndex)) == false &&
world.getFaction(factionIndex)->isAlly(world.getThisFaction()) == false) {
win = false;
}
}
}
}
if (win) {
for (int factionIndex = 0; factionIndex < world.getFactionCount(); ++factionIndex) {
if (world.getFaction(factionIndex)->getPersonalityType() != fpt_Observer) {
if (world.getFaction(factionIndex)->isAlly(world.getThisFaction())) {
world.getStats()->setVictorious(factionIndex);
}
}
}
bool wasGameOverAlready = gameOver;
gameOver = true;
// Only need to process winning once
if(wasGameOverAlready == false) {
if (this->gameSettings.isNetworkGame() == false ||
this->gameSettings.getEnableObserverModeAtEndGame() == true) {
// Let the happy winner view everything left in the world
// This caused too much LAG for network games
if (this->gameSettings.isNetworkGame() == false) {
Renderer::getInstance().setPhotoMode(true);
gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT);
}
// END
}
scriptManager.onGameOver(win);
showWinMessageBox();
}
}
}
}
void Game::checkWinnerStandard() {
if(world.getFactionCount() <= 0) {
return;
}
if(this->masterserverMode == true ||
world.getThisFaction()->getPersonalityType() == fpt_Observer) {
checkWinnerStandardHeadlessOrObserver();
}
else {
checkWinnerStandardPlayer();
}
}
void Game::checkWinnerScripted() {
if(scriptManager.getIsGameOver()) {
bool wasGameOverAlready = gameOver;
gameOver = true;
for(int index = 0; index < world.getFactionCount(); ++index) {
if(scriptManager.getPlayerModifiers(index)->getWinner()) {
world.getStats()->setVictorious(index);
}
}
// Only need to process winning once
if(wasGameOverAlready == false) {
if( this->gameSettings.isNetworkGame() == false ||
this->gameSettings.getEnableObserverModeAtEndGame() == true) {
// Let the happy winner view everything left in the world
// This caused too much LAG for network games
if(this->gameSettings.isNetworkGame() == false) {
Renderer::getInstance().setPhotoMode(true);
gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT);
}
// END
}
if(this->masterserverMode == true ||
world.getThisFaction()->getPersonalityType() == fpt_Observer) {
showWinMessageBox();
}
else {
scriptManager.onGameOver(scriptManager.getPlayerModifiers(world.getThisFactionIndex())->getWinner());
if(scriptManager.getPlayerModifiers(world.getThisFactionIndex())->getWinner()){
showWinMessageBox();
}
else {
showLoseMessageBox();
}
}
}
}
}
bool Game::isFlagType1BitEnabled(FlagTypes1 type) const {
return ((gameSettings.getFlagTypes1() & (uint32)type) == (uint32)type);
}
bool Game::factionLostGame(int factionIndex) {
return factionLostGame(world.getFaction(factionIndex));
}
bool Game::factionLostGame(const Faction *faction) {
if(faction != NULL) {
for(int factionIndex=0; factionIndex<faction->getUnitCount(); ++factionIndex) {
const UnitType *ut = faction->getUnit(factionIndex)->getType();
if(ut->getCountInVictoryConditions() == ucvcNotSet) {
if(faction->getUnit(factionIndex)->getType()->hasSkillClass(scBeBuilt)) {
return false;
}
}
else if(ut->getCountInVictoryConditions() == ucvcTrue) {
return false;
}
}
}
return true;
}
bool Game::hasBuilding(const Faction *faction) {
if(faction != NULL) {
for(int i=0; i<faction->getUnitCount(); ++i) {
if(faction->getUnit(i)->getType()->hasSkillClass(scBeBuilt)) {
return true;
}
}
}
return false;
}
void Game::incSpeed() {
if(disableSpeedChange == true) {
return;
}
Lang &lang= Lang::getInstance();
if(this->speed < Config::getInstance().getInt("FastSpeedLoops")) {
if(this->speed == 0) {
this->speed = 1;
}
else {
this->speed++;
}
console.addLine(lang.getString("GameSpeedSet")+" "+((this->speed == 0)?lang.getString("Slow") : (this->speed == 1)?lang.getString("Normal"):"x"+intToStr(this->speed)));
}
}
void Game::decSpeed() {
if(disableSpeedChange == true) {
return;
}
Lang &lang= Lang::getInstance();
if(this->speed > 0) {
this->speed--;
console.addLine(lang.getString("GameSpeedSet")+" "+((this->speed == 0)?lang.getString("Slow") : (this->speed == 1)?lang.getString("Normal"):"x"+intToStr(this->speed)));
}
}
void Game::setPaused(bool value,bool forceAllowPauseStateChange,bool clearCaches, bool joinNetworkGame) {
bool speedChangesAllowed= !NetworkManager::getInstance().isNetworkGame();
//printf("Toggle pause value = %d, speedChangesAllowed = %d, forceAllowPauseStateChange = %d\n",value,speedChangesAllowed,forceAllowPauseStateChange);
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);
//printf("Line: %d setPaused value: %d clearCaches: %d forceAllowPauseStateChange: %d speedChangesAllowed: %d pausedForJoinGame: %d joinNetworkGame: %d\n",__LINE__,value,clearCaches,forceAllowPauseStateChange,speedChangesAllowed,pausedForJoinGame,joinNetworkGame);
if(forceAllowPauseStateChange == true || speedChangesAllowed == true) {
//printf("setPaused paused = %d, value = %d\n",paused,value);
NetworkManager &networkManager= NetworkManager::getInstance();
// Cannot change pause state while client is joining in progress game
if(pausedForJoinGame == true && joinNetworkGame == false &&
networkManager.getNetworkRole() == nrServer) {
ServerInterface *server = NetworkManager::getInstance().getServerInterface();
Lang &lang= Lang::getInstance();
const vector<string> languageList = this->gameSettings.getUniqueNetworkPlayerLanguages();
bool haveClientConnectedButNoReady = false;
for(int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
MutexSafeWrapper safeMutex(server->getSlotMutex(faction->getStartLocationIndex()),CODE_AT_LINE);
ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex(),false);
if(slot != NULL && slot->isConnected() == true && slot->isReady() == false) {
for(unsigned int i = 0; i < languageList.size(); ++i) {
char szMsg[8096]="";
if(lang.hasString("JoinPlayerToCurrentGameLaunch",languageList[i]) == true) {
snprintf(szMsg,8096,lang.getString("JoinPlayerToCurrentGameLaunch",languageList[i]).c_str(), slot->getName().c_str());
}
else {
snprintf(szMsg,8096,"Player: %s is about to join the game, please wait...",slot->getName().c_str());
}
safeMutex.ReleaseLock();
bool localEcho = lang.isLanguageLocal(languageList[i]);
server->sendTextMessage(szMsg,-1, localEcho,languageList[i]);
sleep(1);
haveClientConnectedButNoReady = true;
}
}
}
if(haveClientConnectedButNoReady == true) {
return;
}
}
Lang &lang= Lang::getInstance();
if(value == false) {
console.addLine(lang.getString("GameResumed"));
bool wasPausedForJoinGame = pausedForJoinGame;
paused= false;
pausedForJoinGame = false;
pausedBeforeJoinGame = false;
pauseStateChanged = true;
if(clearCaches == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"game.cpp line: %d Clear Caches for resume in progress game\n",__LINE__);
//printf("Line: %d Clear Caches for resume in progress game\n",__LINE__);
world.clearCaches();
for(int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
faction->clearCaches();
}
world.refreshAllUnitExplorations();
}
setupPopupMenus(false);
if(networkManager.getNetworkRole() == nrClient &&
wasPausedForJoinGame == true) {
initialResumeSpeedLoops = true;
}
commander.setPauseNetworkCommands(false);
}
else {
console.addLine(lang.getString("GamePaused"));
if(joinNetworkGame == true) {
pausedBeforeJoinGame = paused;
}
paused= true;
pausedForJoinGame = joinNetworkGame;
pauseStateChanged = true;
if(clearCaches == true) {
//printf("Line: %d Clear Caches for resume in progress game\n",__LINE__);
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"game.cpp line: %d Clear Caches for resume in progress game\n",__LINE__);
world.clearCaches();
for(int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
faction->clearCaches();
}
world.refreshAllUnitExplorations();
}
pauseRequestSent=false;
commander.setPauseNetworkCommands(joinNetworkGame);
}
//printf("setPaused new paused = %d\n",paused);
}
}
bool Game::getPaused()
{
bool speedChangesAllowed= !NetworkManager::getInstance().isNetworkGame();
if(speedChangesAllowed){
if(popupMenu.getVisible() == true || popupMenuSwitchTeams.getVisible() == true){
return true;
}
// if(mainMessageBox.getEnabled() == true || errorMessageBox.getEnabled() == true){
// return true;
// }
if(currentUIState != NULL) {
return true;
}
}
return paused;
}
int Game::getUpdateLoops() {
if(commander.hasReplayCommandListForFrame() == true) {
return 1;
}
if(getPaused()) {
return 0;
}
else if(this->speed == 0) {
return updateFps % 2 == 0? 1: 0;
}
else
return this->speed;
}
void Game::showLoseMessageBox() {
Lang &lang= Lang::getInstance();
NetworkManager &networkManager= NetworkManager::getInstance();
if(networkManager.isNetworkGame() == true && networkManager.getNetworkRole() == nrServer) {
showMessageBox(lang.getString("YouLose")+" "+lang.getString("ExitGameServer?"), lang.getString("BattleOver"), false);
}
else {
showMessageBox(lang.getString("YouLose")+" "+lang.getString("ExitGameMenu?"), lang.getString("BattleOver"), false);
}
}
void Game::showWinMessageBox() {
Lang &lang= Lang::getInstance();
if(this->masterserverMode == true || world.getThisFaction()->getPersonalityType() == fpt_Observer) {
showMessageBox(lang.getString("GameOver")+" "+lang.getString("ExitGameMenu?"), lang.getString("BattleOver"), false);
}
else {
showMessageBox(lang.getString("YouWin")+" "+lang.getString("ExitGameMenu?"), lang.getString("BattleOver"), false);
}
}
void Game::showMessageBox(const string &text, const string &header, bool toggle) {
if(toggle == false) {
mainMessageBox.setEnabled(false);
}
if(mainMessageBox.getEnabled() == false) {
mainMessageBox.setText(text);
mainMessageBox.setHeader(header);
mainMessageBox.setEnabled(true);
}
else {
mainMessageBox.setEnabled(false);
}
}
void Game::showErrorMessageBox(const string &text, const string &header, bool toggle) {
if(toggle == false) {
errorMessageBox.setEnabled(false);
}
if(errorMessageBox.getEnabled() == false) {
errorMessageBox.setText(text);
errorMessageBox.setHeader(header);
errorMessageBox.setEnabled(true);
}
else {
errorMessageBox.setEnabled(false);
}
}
void Game::startPerformanceTimer() {
captureAvgTestStatus = true;
updateFpsAvgTest = -1;
renderFpsAvgTest = -1;
}
void Game::endPerformanceTimer() {
captureAvgTestStatus = false;
}
Vec2i Game::getPerformanceTimerResults() {
Vec2i results(this->updateFpsAvgTest,this->renderFpsAvgTest);
return results;
}
void Game::consoleAddLine(string line) {
console.addLine(line);
}
void Game::toggleTeamColorMarker() {
renderExtraTeamColor++;
renderExtraTeamColor=renderExtraTeamColor%4;
}
void Game::addNetworkCommandToReplayList(NetworkCommand* networkCommand, int worldFrameCount) {
Config &config= Config::getInstance();
if(config.getBool("SaveCommandsForReplay","false") == true) {
replayCommandList.push_back(make_pair(worldFrameCount,*networkCommand));
}
}
void Game::renderVideoPlayer() {
if(videoPlayer != NULL) {
if(videoPlayer->isPlaying() == true) {
videoPlayer->playFrame(false);
}
else {
delete videoPlayer;
videoPlayer = NULL;
}
}
}
void Game::playStaticVideo(const string &playVideo) {
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false &&
::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == true) {
//togglePauseGame(true,true);
tryPauseToggle(true);
setupRenderForVideo();
// Context *c= GraphicsInterface::getInstance().getCurrentContext();
// SDL_Surface *screen = static_cast<ContextGl*>(c)->getPlatformContextGlPtr()->getScreen();
//
// string vlcPluginsPath = Config::getInstance().getString("VideoPlayerPluginsPath","");
// //printf("screen->w = %d screen->h = %d screen->format->BitsPerPixel = %d\n",screen->w,screen->h,screen->format->BitsPerPixel);
// Shared::Graphics::VideoPlayer player(playVideo.c_str(),
// screen,
// 0,0,
// screen->w,
// screen->h,
// screen->format->BitsPerPixel,
// vlcPluginsPath,
// SystemFlags::VERBOSE_MODE_ENABLED);
// player.PlayVideo();
//}
//tryPauseToggle(false);
playStreamingVideo(playVideo);
playingStaticVideo = true;
}
}
void Game::playStreamingVideo(const string &playVideo) {
if(videoPlayer == NULL) {
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false &&
::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == true) {
Context *c= GraphicsInterface::getInstance().getCurrentContext();
SDL_Surface *screen = static_cast<ContextGl*>(c)->getPlatformContextGlPtr()->getScreen();
string vlcPluginsPath = Config::getInstance().getString("VideoPlayerPluginsPath","");
videoPlayer = new ::Shared::Graphics::VideoPlayer(
&Renderer::getInstance(),
playVideo,
"",
screen,
0,0,
screen->w,
screen->h,
screen->format->BitsPerPixel,
false,
vlcPluginsPath,
SystemFlags::VERBOSE_MODE_ENABLED);
}
}
else {
if(videoPlayer->isPlaying() == false) {
delete videoPlayer;
videoPlayer = NULL;
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false &&
::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == true) {
Context *c= GraphicsInterface::getInstance().getCurrentContext();
SDL_Surface *screen = static_cast<ContextGl*>(c)->getPlatformContextGlPtr()->getScreen();
string vlcPluginsPath = Config::getInstance().getString("VideoPlayerPluginsPath","");
videoPlayer = new ::Shared::Graphics::VideoPlayer(
&Renderer::getInstance(),
playVideo,
"",
screen,
0,0,
screen->w,
screen->h,
screen->format->BitsPerPixel,
false,
vlcPluginsPath,
SystemFlags::VERBOSE_MODE_ENABLED);
}
}
}
if(videoPlayer != NULL) {
videoPlayer->initPlayer();
}
}
void Game::stopStreamingVideo(const string &playVideo) {
if(videoPlayer != NULL) {
videoPlayer->StopVideo();
}
}
void Game::stopAllVideo() {
if(videoPlayer != NULL) {
videoPlayer->StopVideo();
}
}
bool Game::clientLagHandler(int slotIndex,bool networkPauseGameForLaggedClients) {
if(networkPauseGameForLaggedClients == true) {
printf("**WARNING** Detected lag from client: %d networkPauseGameForLaggedClients: %d\n",slotIndex,networkPauseGameForLaggedClients);
}
else {
printf("==> Requested Resume Game after Pause for lagging client(s)...\n");
}
this->networkPauseGameForLaggedClientsRequested = networkPauseGameForLaggedClients;
this->networkResumeGameForLaggedClientsRequested = !networkPauseGameForLaggedClients;
return true;
}
void Game::saveGame(){
string file = this->saveGame(GameConstants::saveGameFilePattern);
char szBuf[8096]="";
Lang &lang= Lang::getInstance();
snprintf(szBuf,8096,lang.getString("GameSaved","",true).c_str(),file.c_str());
console.addLine(szBuf);
Config &config= Config::getInstance();
config.setString("LastSavedGame",file);
config.save();
}
string Game::saveGame(string name, string path) {
Config &config= Config::getInstance();
// auto name file if using saved file pattern string
if(name == GameConstants::saveGameFilePattern) {
time_t curTime = time(NULL);
struct tm *loctime = localtime (&curTime);
char szBuf2[100]="";
strftime(szBuf2,100,"%Y%m%d_%H%M%S",loctime);
char szBuf[8096]="";
snprintf(szBuf,8096,name.c_str(),szBuf2);
name = szBuf;
}
else if(name == GameConstants::saveGameFileAutoTestDefault) {
time_t curTime = time(NULL);
struct tm *loctime = localtime (&curTime);
char szBuf2[100]="";
strftime(szBuf2,100,"%Y%m%d_%H%M%S",loctime);
char szBuf[8096]="";
snprintf(szBuf,8096,name.c_str(),szBuf2);
name = szBuf;
}
// Save the file now
string saveGameFile = path + name;
if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
saveGameFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + saveGameFile;
}
else {
string userData = config.getString("UserData_Root","");
if(userData != "") {
endPathWithSlash(userData);
}
saveGameFile = userData + saveGameFile;
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Saving game to [%s]\n",saveGameFile.c_str());
// This condition will re-play all the commands from a replay file
// INSTEAD of saving from a saved game.
if(config.getBool("SaveCommandsForReplay","false") == true) {
std::map<string,string> mapTagReplacements;
XmlTree xmlTreeSaveGame(XML_RAPIDXML_ENGINE);
xmlTreeSaveGame.init("megaglest-saved-game");
XmlNode *rootNodeReplay = xmlTreeSaveGame.getRootNode();
//std::map<string,string> mapTagReplacements;
time_t now = time(NULL);
struct tm *loctime = localtime (&now);
char szBuf[4096]="";
strftime(szBuf,4095,"%Y-%m-%d %H:%M:%S",loctime);
rootNodeReplay->addAttribute("version",glestVersionString, mapTagReplacements);
rootNodeReplay->addAttribute("timestamp",szBuf, mapTagReplacements);
XmlNode *gameNodeReplay = rootNodeReplay->addChild("Game");
gameSettings.saveGame(gameNodeReplay);
gameNodeReplay->addAttribute("LastWorldFrameCount",intToStr(world.getFrameCount()), mapTagReplacements);
for(unsigned int i = 0; i < replayCommandList.size(); ++i) {
std::pair<int,NetworkCommand> &cmd = replayCommandList[i];
XmlNode *networkCommandNode = cmd.second.saveGame(gameNodeReplay);
networkCommandNode->addAttribute("worldFrameCount",intToStr(cmd.first), mapTagReplacements);
}
string replayFile = saveGameFile + ".replay";
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Saving game replay commands to [%s]\n",replayFile.c_str());
xmlTreeSaveGame.save(replayFile);
}
XmlTree xmlTree;
xmlTree.init("megaglest-saved-game");
XmlNode *rootNode = xmlTree.getRootNode();
std::map<string,string> mapTagReplacements;
time_t now = time(NULL);
struct tm *loctime = localtime (&now);
char szBuf[4096]="";
strftime(szBuf,4095,"%Y-%m-%d %H:%M:%S",loctime);
rootNode->addAttribute("version",glestVersionString, mapTagReplacements);
rootNode->addAttribute("timestamp",szBuf, mapTagReplacements);
XmlNode *gameNode = rootNode->addChild("Game");
//World world;
world.saveGame(gameNode);
//AiInterfaces aiInterfaces;
for(unsigned int i = 0; i < aiInterfaces.size(); ++i) {
AiInterface *aiIntf = aiInterfaces[i];
if(aiIntf != NULL) {
aiIntf->saveGame(gameNode);
}
}
//Gui gui;
gui.saveGame(gameNode);
//GameCamera gameCamera;
gameCamera.saveGame(gameNode);
//Commander commander;
//Console console;
//ChatManager chatManager;
//ScriptManager scriptManager;
scriptManager.saveGame(gameNode);
//misc
//Checksum checksum;
gameNode->addAttribute("checksum",intToStr(checksum.getSum()), mapTagReplacements);
//string loadingText;
// int mouse2d;
gameNode->addAttribute("mouse2d",intToStr(mouse2d), mapTagReplacements);
// int mouseX;
gameNode->addAttribute("mouseX",intToStr(mouseX), mapTagReplacements);
// int mouseY; //coords win32Api
gameNode->addAttribute("mouseY",intToStr(mouseY), mapTagReplacements);
// Vec2i mouseCellPos;
gameNode->addAttribute("mouseCellPos",mouseCellPos.getString(), mapTagReplacements);
// int updateFps, lastUpdateFps, avgUpdateFps;
// int totalRenderFps, renderFps, lastRenderFps, avgRenderFps,currentAvgRenderFpsTotal;
//Uint64 tickCount;
gameNode->addAttribute("tickCount",intToStr(tickCount), mapTagReplacements);
//bool paused;
gameNode->addAttribute("paused",intToStr(paused), mapTagReplacements);
//bool gameOver;
gameNode->addAttribute("gameOver",intToStr(gameOver), mapTagReplacements);
//bool renderNetworkStatus;
//bool showFullConsole;
//bool mouseMoved;
//float scrollSpeed;
gameNode->addAttribute("scrollSpeed",floatToStr(scrollSpeed,6), mapTagReplacements);
//bool camLeftButtonDown;
//bool camRightButtonDown;
//bool camUpButtonDown;
//bool camDownButtonDown;
//Speed speed;
gameNode->addAttribute("speed",intToStr(speed), mapTagReplacements);
//GraphicMessageBox mainMessageBox;
//GraphicMessageBox errorMessageBox;
//misc ptr
//ParticleSystem *weatherParticleSystem;
if(weatherParticleSystem != NULL) {
weatherParticleSystem->saveGame(gameNode);
}
//GameSettings gameSettings;
gameSettings.saveGame(gameNode);
//Vec2i lastMousePos;
gameNode->addAttribute("lastMousePos",lastMousePos.getString(), mapTagReplacements);
//time_t lastRenderLog2d;
gameNode->addAttribute("lastRenderLog2d",intToStr(lastRenderLog2d), mapTagReplacements);
//DisplayMessageFunction originalDisplayMsgCallback;
//bool isFirstRender;
gameNode->addAttribute("isFirstRender",intToStr(isFirstRender), mapTagReplacements);
//bool quitTriggeredIndicator;
//int original_updateFps;
gameNode->addAttribute("original_updateFps",intToStr(original_updateFps), mapTagReplacements);
//int original_cameraFps;
gameNode->addAttribute("original_cameraFps",intToStr(original_cameraFps), mapTagReplacements);
//bool captureAvgTestStatus;
gameNode->addAttribute("captureAvgTestStatus",intToStr(captureAvgTestStatus), mapTagReplacements);
//int updateFpsAvgTest;
gameNode->addAttribute("updateFpsAvgTest",intToStr(updateFpsAvgTest), mapTagReplacements);
//int renderFpsAvgTest;
gameNode->addAttribute("renderFpsAvgTest",intToStr(renderFpsAvgTest), mapTagReplacements);
//int renderExtraTeamColor;
gameNode->addAttribute("renderExtraTeamColor",intToStr(renderExtraTeamColor), mapTagReplacements);
//static const int renderTeamColorCircleBit=1;
//static const int renderTeamColorPlaneBit=2;
//bool photoModeEnabled;
gameNode->addAttribute("photoModeEnabled",intToStr(photoModeEnabled), mapTagReplacements);
//bool visibleHUD;
gameNode->addAttribute("visibleHUD",intToStr(visibleHUD), mapTagReplacements);
//bool timeDisplay
gameNode->addAttribute("timeDisplay",intToStr(timeDisplay), mapTagReplacements);
//bool withRainEffect;
gameNode->addAttribute("withRainEffect",intToStr(withRainEffect), mapTagReplacements);
//Program *program;
//bool gameStarted;
gameNode->addAttribute("gameStarted",intToStr(gameStarted), mapTagReplacements);
//time_t lastMaxUnitCalcTime;
gameNode->addAttribute("lastMaxUnitCalcTime",intToStr(lastMaxUnitCalcTime), mapTagReplacements);
//PopupMenu popupMenu;
//PopupMenu popupMenuSwitchTeams;
//std::map<int,int> switchTeamIndexMap;
//GraphicMessageBox switchTeamConfirmMessageBox;
//int exitGamePopupMenuIndex;
//int joinTeamPopupMenuIndex;
//int pauseGamePopupMenuIndex;
//int keyboardSetupPopupMenuIndex;
//GLuint statelist3dMenu;
//ProgramState *currentUIState;
//bool masterserverMode;
//StrSound *currentAmbientSound;
//time_t lastNetworkPlayerConnectionCheck;
gameNode->addAttribute("lastNetworkPlayerConnectionCheck",intToStr(lastNetworkPlayerConnectionCheck), mapTagReplacements);
//time_t lastMasterServerGameStatsDump;
gameNode->addAttribute("lastMasterServerGameStatsDump",intToStr(lastMasterServerGameStatsDump), mapTagReplacements);
XmlNode *unitHighlightListNode = gameNode->addChild("unitHighlightList");
//for(unsigned int i = 0; i < unitHighlightList.size(); ++i) {
for(std::map<int,HighlightSpecialUnitInfo>::iterator iterMap = unitHighlightList.begin();
iterMap != unitHighlightList.end(); ++iterMap) {
HighlightSpecialUnitInfo &info = iterMap->second;
XmlNode *infoNode = unitHighlightListNode->addChild("info");
infoNode->addAttribute("unitid",intToStr(iterMap->first), mapTagReplacements);
infoNode->addAttribute("radius",floatToStr(info.radius,6), mapTagReplacements);
infoNode->addAttribute("thickness",floatToStr(info.thickness,6), mapTagReplacements);
infoNode->addAttribute("color",info.color.getString(), mapTagReplacements);
}
gameNode->addAttribute("disableSpeedChange",intToStr(disableSpeedChange), mapTagReplacements);
xmlTree.save(saveGameFile);
if(masterserverMode == false) {
// take Screenshot
string jpgFileName=saveGameFile+".jpg";
// menu is already disabled, last rendered screen is still with enabled one. Lets render again:
render3d();
render2d();
Renderer::getInstance().saveScreen(jpgFileName,config.getInt("SaveGameScreenshotWidth","800"),config.getInt("SaveGameScreenshotHeight","600"));
}
return saveGameFile;
}
void Game::loadGame(string name,Program *programPtr,bool isMasterserverMode,const GameSettings *joinGameSettings) {
Config &config= Config::getInstance();
// This condition will re-play all the commands from a replay file
// INSTEAD of saving from a saved game.
if(joinGameSettings == NULL && config.getBool("SaveCommandsForReplay","false") == true) {
XmlTree xmlTreeReplay(XML_RAPIDXML_ENGINE);
std::map<string,string> mapExtraTagReplacementValues;
xmlTreeReplay.load(name + ".replay", Properties::getTagReplacementValues(&mapExtraTagReplacementValues),true);
const XmlNode *rootNode= xmlTreeReplay.getRootNode();
if(rootNode->hasChild("megaglest-saved-game") == true) {
rootNode = rootNode->getChild("megaglest-saved-game");
}
//const XmlNode *versionNode= rootNode->getChild("megaglest-saved-game");
const XmlNode *versionNode= rootNode;
Lang &lang= Lang::getInstance();
string gameVer = versionNode->getAttribute("version")->getValue();
if(gameVer != glestVersionString && checkVersionComptability(gameVer, glestVersionString) == false){
char szBuf[8096]="";
snprintf(szBuf,8096,lang.getString("SavedGameBadVersion").c_str(),gameVer.c_str(),glestVersionString.c_str());
throw megaglest_runtime_error(szBuf,true);
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Found saved game version that matches your application version: [%s] --> [%s]\n",gameVer.c_str(),glestVersionString.c_str());
XmlNode *gameNode = rootNode->getChild("Game");
GameSettings newGameSettingsReplay;
newGameSettingsReplay.loadGame(gameNode);
//printf("Loading scenario [%s]\n",newGameSettingsReplay.getScenarioDir().c_str());
if(newGameSettingsReplay.getScenarioDir() != "" && fileExists(newGameSettingsReplay.getScenarioDir()) == false) {
newGameSettingsReplay.setScenarioDir(Scenario::getScenarioPath(Config::getInstance().getPathListForType(ptScenarios),newGameSettingsReplay.getScenario()));
//printf("Loading scenario #2 [%s]\n",newGameSettingsReplay.getScenarioDir().c_str());
}
//GameSettings newGameSettings;
//newGameSettings.loadGame(gameNode);
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Game settings loaded\n");
NetworkManager &networkManager= NetworkManager::getInstance();
networkManager.end();
networkManager.init(nrServer,true);
Game *newGame = new Game(programPtr, &newGameSettingsReplay, isMasterserverMode);
newGame->lastworldFrameCountForReplay = gameNode->getAttribute("LastWorldFrameCount")->getIntValue();
vector<XmlNode *> networkCommandNodeList = gameNode->getChildList("NetworkCommand");
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("networkCommandNodeList.size() = " MG_SIZE_T_SPECIFIER "\n",networkCommandNodeList.size());
for(unsigned int i = 0; i < networkCommandNodeList.size(); ++i) {
XmlNode *node = networkCommandNodeList[i];
int worldFrameCount = node->getAttribute("worldFrameCount")->getIntValue();
NetworkCommand command;
command.loadGame(node);
newGame->commander.addToReplayCommandList(command,worldFrameCount);
}
programPtr->setState(newGame);
return;
}
XmlTree xmlTree(XML_RAPIDXML_ENGINE);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Before load of XML\n");
std::map<string,string> mapExtraTagReplacementValues;
xmlTree.load(name, Properties::getTagReplacementValues(&mapExtraTagReplacementValues),true);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("After load of XML\n");
const XmlNode *rootNode= xmlTree.getRootNode();
if(rootNode->hasChild("megaglest-saved-game") == true) {
rootNode = rootNode->getChild("megaglest-saved-game");
}
//const XmlNode *versionNode= rootNode->getChild("megaglest-saved-game");
const XmlNode *versionNode= rootNode;
Lang &lang= Lang::getInstance();
string gameVer = versionNode->getAttribute("version")->getValue();
// this is the version check for loading normal save games from menu_state_load_game
if (gameVer != glestVersionString
&& (compareMajorMinorVersion(gameVer, lastCompatibleSaveGameVersionString) < 0
|| compareMajorMinorVersion(glestVersionString, gameVer) < 0)) {
char szBuf[8096]="";
snprintf(szBuf,8096,lang.getString("SavedGameBadVersion").c_str(),gameVer.c_str(),glestVersionString.c_str());
throw megaglest_runtime_error(szBuf,true);
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Found saved game version that matches your application version: [%s] --> [%s]\n",gameVer.c_str(),glestVersionString.c_str());
XmlNode *gameNode = rootNode->getChild("Game");
GameSettings newGameSettings;
if(joinGameSettings != NULL) {
newGameSettings = *joinGameSettings;
XmlNode *worldNode = gameNode->getChild("World");
XmlNode *guiNode = gameNode->getChild("Gui");
XmlNode *selectionNode = guiNode->getChild("Selection");
XmlNode *statsNode = worldNode->getChild("Stats");
XmlNode *minimapNode = worldNode->getChild("Minimap");
if(gameVer != glestVersionString && checkVersionComptability(gameVer, glestVersionString) == false){
char szBuf[8096]="";
snprintf(szBuf,8096,lang.getString("SavedGameBadVersion").c_str(),gameVer.c_str(),glestVersionString.c_str());
throw megaglest_runtime_error(szBuf,true);
}
// This is explored fog of war for the host player, clear it
minimapNode->clearChild("fowPixmap1");
NetworkManager &networkManager= NetworkManager::getInstance();
//NetworkRole role = networkManager.getNetworkRole();
ClientInterface *clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
for(int i= 0; i<newGameSettings.getFactionCount(); ++i) {
//replace by network
if(newGameSettings.getFactionControl(i)==ctHuman) {
newGameSettings.setFactionControl(i, ctNetwork);
}
//set the faction index
if(newGameSettings.getStartLocationIndex(i) == clientInterface->getPlayerIndex()) {
newGameSettings.setThisFactionIndex(i);
newGameSettings.setFactionControl(i, ctNetwork);
worldNode->getAttribute("thisFactionIndex")->setValue(intToStr(i));
//worldNode->getAttribute("thisTeamIndex")->setValue(intToStr(newGameSettings.getTeam(i)));
XmlNode *factionNode = worldNode->getChild("Faction",i);
factionNode->getAttribute("thisFaction")->setValue(intToStr(i));
factionNode->getAttribute("control")->setValue(intToStr(ctNetwork));
selectionNode->getAttribute("factionIndex")->setValue(intToStr(i));
//selectionNode->getAttribute("teamIndex")->setValue(intToStr(newGameSettings.getTeam(i)));
statsNode->getAttribute("thisFactionIndex")->setValue(intToStr(i));
}
else {
XmlNode *factionNode = worldNode->getChild("Faction",i);
factionNode->getAttribute("thisFaction")->setValue(intToStr(0));
}
}
}
else {
newGameSettings.loadGame(gameNode);
//printf("Loading scenario [%s]\n",newGameSettings.getScenarioDir().c_str());
if(newGameSettings.getScenarioDir() != "" && fileExists(newGameSettings.getScenarioDir()) == false) {
newGameSettings.setScenarioDir(Scenario::getScenarioPath(Config::getInstance().getPathListForType(ptScenarios),newGameSettings.getScenario()));
//printf("Loading scenario #2 [%s]\n",newGameSettings.getScenarioDir().c_str());
}
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Game settings loaded\n");
if(joinGameSettings == NULL) {
NetworkManager &networkManager= NetworkManager::getInstance();
networkManager.end();
networkManager.init(nrServer,true);
}
Game *newGame = new Game(programPtr, &newGameSettings, isMasterserverMode);
newGame->loadGameNode = gameNode;
newGame->inJoinGameLoading = (joinGameSettings != NULL);
// newGame->mouse2d = gameNode->getAttribute("mouse2d")->getIntValue();
// int mouseX;
// newGame->mouseX = gameNode->getAttribute("mouseX")->getIntValue();
// int mouseY; //coords win32Api
// newGame->mouseY = gameNode->getAttribute("mouseY")->getIntValue();
// Vec2i mouseCellPos;
// newGame->mouseCellPos = Vec2i::strToVec2(gameNode->getAttribute("mouseCellPos")->getValue());
// int updateFps, lastUpdateFps, avgUpdateFps;
// int totalRenderFps, renderFps, lastRenderFps, avgRenderFps,currentAvgRenderFpsTotal;
//Uint64 tickCount;
newGame->tickCount = gameNode->getAttribute("tickCount")->getIntValue();
//bool paused;
if(newGame->inJoinGameLoading==true){
newGame->paused = gameNode->getAttribute("paused")->getIntValue() != 0;
}else{
//newGame->paused = gameNode->getAttribute("paused")->getIntValue() != 0;
newGame->paused = true;
}
if(newGame->paused) newGame->console.addLine(lang.getString("GamePaused"));
//bool gameOver;
newGame->gameOver = gameNode->getAttribute("gameOver")->getIntValue() != 0;
//bool renderNetworkStatus;
//bool showFullConsole;
//bool mouseMoved;
//float scrollSpeed;
// newGame->scrollSpeed = gameNode->getAttribute("scrollSpeed")->getFloatValue();
//bool camLeftButtonDown;
//bool camRightButtonDown;
//bool camUpButtonDown;
//bool camDownButtonDown;
//Speed speed;
//gameNode->addAttribute("speed",intToStr(speed), mapTagReplacements);
//GraphicMessageBox mainMessageBox;
//GraphicMessageBox errorMessageBox;
//misc ptr
//ParticleSystem *weatherParticleSystem;
// if(weatherParticleSystem != NULL) {
// weatherParticleSystem->saveGame(gameNode);
// }
//GameSettings gameSettings;
// gameSettings.saveGame(gameNode);
//Vec2i lastMousePos;
// gameNode->addAttribute("lastMousePos",lastMousePos.getString(), mapTagReplacements);
//time_t lastRenderLog2d;
// gameNode->addAttribute("lastRenderLog2d",intToStr(lastRenderLog2d), mapTagReplacements);
//DisplayMessageFunction originalDisplayMsgCallback;
//bool isFirstRender;
// gameNode->addAttribute("isFirstRender",intToStr(isFirstRender), mapTagReplacements);
//bool quitTriggeredIndicator;
//int original_updateFps;
// gameNode->addAttribute("original_updateFps",intToStr(original_updateFps), mapTagReplacements);
//int original_cameraFps;
// gameNode->addAttribute("original_cameraFps",intToStr(original_cameraFps), mapTagReplacements);
//bool captureAvgTestStatus;
// gameNode->addAttribute("captureAvgTestStatus",intToStr(captureAvgTestStatus), mapTagReplacements);
//int updateFpsAvgTest;
// gameNode->addAttribute("updateFpsAvgTest",intToStr(updateFpsAvgTest), mapTagReplacements);
//int renderFpsAvgTest;
// gameNode->addAttribute("renderFpsAvgTest",intToStr(renderFpsAvgTest), mapTagReplacements);
//int renderExtraTeamColor;
newGame->renderExtraTeamColor = gameNode->getAttribute("renderExtraTeamColor")->getIntValue();
//static const int renderTeamColorCircleBit=1;
//static const int renderTeamColorPlaneBit=2;
//bool photoModeEnabled;
//gameNode->addAttribute("photoModeEnabled",intToStr(photoModeEnabled), mapTagReplacements);
newGame->photoModeEnabled = gameNode->getAttribute("photoModeEnabled")->getIntValue() != 0;
//bool visibleHUD;
//gameNode->addAttribute("visibleHUD",intToStr(visibleHUD), mapTagReplacements);
newGame->visibleHUD = gameNode->getAttribute("visibleHUD")->getIntValue() != 0;
newGame->timeDisplay = gameNode->getAttribute("timeDisplay")->getIntValue() != 0;
//bool withRainEffect;
//gameNode->addAttribute("withRainEffect",intToStr(withRainEffect), mapTagReplacements);
newGame->withRainEffect = gameNode->getAttribute("withRainEffect")->getIntValue() != 0;
//Program *program;
if(joinGameSettings == NULL) {
if(gameNode->hasChild("unitHighlightList") == true) {
XmlNode *unitHighlightListNode = gameNode->getChild("unitHighlightList");
vector<XmlNode *> infoNodeList = unitHighlightListNode->getChildList("info");
for(unsigned int i = 0; i < infoNodeList.size(); ++i) {
XmlNode *infoNode = infoNodeList[i];
int unitId = infoNode->getAttribute("radius")->getIntValue();
HighlightSpecialUnitInfo info;
info.radius = infoNode->getAttribute("radius")->getFloatValue();
info.thickness = infoNode->getAttribute("thickness")->getFloatValue();
info.color = Vec4f::strToVec4(infoNode->getAttribute("color")->getValue());
newGame->unitHighlightList[unitId] = info;
}
}
}
newGame->timeDisplay = gameNode->getAttribute("timeDisplay")->getIntValue() != 0;
if(gameNode->hasAttribute("disableSpeedChange") == true) {
newGame->disableSpeedChange = gameNode->getAttribute("disableSpeedChange")->getIntValue() != 0;
}
//bool gameStarted;
//gameNode->addAttribute("gameStarted",intToStr(gameStarted), mapTagReplacements);
// newGame->gameStarted = gameNode->getAttribute("gameStarted")->getIntValue();
//time_t lastMaxUnitCalcTime;
//gameNode->addAttribute("lastMaxUnitCalcTime",intToStr(lastMaxUnitCalcTime), mapTagReplacements);
//PopupMenu popupMenu;
//PopupMenu popupMenuSwitchTeams;
//std::map<int,int> switchTeamIndexMap;
//GraphicMessageBox switchTeamConfirmMessageBox;
//int exitGamePopupMenuIndex;
//int joinTeamPopupMenuIndex;
//int pauseGamePopupMenuIndex;
//int keyboardSetupPopupMenuIndex;
//GLuint statelist3dMenu;
//ProgramState *currentUIState;
//bool masterserverMode;
//StrSound *currentAmbientSound;
//time_t lastNetworkPlayerConnectionCheck;
//gameNode->addAttribute("lastNetworkPlayerConnectionCheck",intToStr(lastNetworkPlayerConnectionCheck), mapTagReplacements);
//time_t lastMasterServerGameStatsDump;
//gameNode->addAttribute("lastMasterServerGameStatsDump",intToStr(lastMasterServerGameStatsDump), mapTagReplacements);
if(joinGameSettings == NULL) {
newGame->gameCamera.loadGame(gameNode);
}
const XmlNode *worldNode = gameNode->getChild("World");
newGame->world.loadGame(worldNode);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Starting Game ...\n");
programPtr->setState(newGame);
}
}}//end namespace