2011-01-20 16:56:30 +01:00
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2005 Martio 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 "scenario.h"
# include <stdexcept>
# include "logger.h"
# include "xml_parser.h"
# include "util.h"
# include "game_util.h"
# include <stdio.h>
2011-03-13 09:23:43 +01:00
# include "platform_common.h"
2011-05-07 00:12:16 +02:00
# include "properties.h"
2011-10-06 20:04:59 +02:00
# include "lang.h"
# include "config.h"
2011-03-13 09:23:43 +01:00
# include "leak_dumper.h"
2011-01-20 16:56:30 +01:00
using namespace Shared : : Xml ;
using namespace Shared : : Util ;
2011-03-13 09:23:43 +01:00
using namespace Shared : : PlatformCommon ;
2011-01-20 16:56:30 +01:00
using namespace std ;
namespace Glest { namespace Game {
// =====================================================
// class Scenario
// =====================================================
Scenario : : ~ Scenario ( ) {
}
2011-01-09 05:49:21 +01:00
Checksum Scenario : : load ( const string & path ) {
2011-10-06 20:04:59 +02:00
//printf("[%s:%s] Line: %d path [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str());
2011-01-20 16:56:30 +01:00
Checksum scenarioChecksum ;
try {
2011-01-09 05:49:21 +01:00
scenarioChecksum . addFile ( path ) ;
checksumValue . addFile ( path ) ;
2011-01-20 16:56:30 +01:00
string name = cutLastExt ( lastDir ( path ) ) ;
2011-11-02 18:17:28 +01:00
char szBuf [ 1024 ] = " " ;
sprintf ( szBuf , Lang : : getInstance ( ) . get ( " LogScreenGameLoadingScenario " , " " , true ) . c_str ( ) , formatString ( name ) . c_str ( ) ) ;
Logger : : getInstance ( ) . add ( szBuf , true ) ;
2011-01-20 16:56:30 +01:00
2011-10-06 20:04:59 +02:00
Scenario : : loadScenarioInfo ( path , & info ) ;
2011-01-20 16:56:30 +01:00
//parse xml
XmlTree xmlTree ;
2011-05-07 00:12:16 +02:00
xmlTree . load ( path , Properties : : getTagReplacementValues ( ) ) ;
2011-01-20 16:56:30 +01:00
const XmlNode * scenarioNode = xmlTree . getRootNode ( ) ;
const XmlNode * scriptsNode = scenarioNode - > getChild ( " scripts " ) ;
for ( int i = 0 ; i < scriptsNode - > getChildCount ( ) ; + + i ) {
const XmlNode * scriptNode = scriptsNode - > getChild ( i ) ;
scripts . push_back ( Script ( getFunctionName ( scriptNode ) , scriptNode - > getText ( ) ) ) ;
}
}
//Exception handling (conversions and so on);
catch ( const exception & e ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , e . what ( ) ) ;
throw runtime_error ( " Error: " + path + " \n " + e . what ( ) ) ;
2011-01-09 05:49:21 +01:00
}
2011-01-20 16:56:30 +01:00
return scenarioChecksum ;
}
2010-03-18 22:26:40 +01:00
int Scenario : : getScenarioPathIndex ( const vector < string > dirList , const string & scenarioName ) {
int iIndex = 0 ;
for ( int idx = 0 ; idx < dirList . size ( ) ; idx + + ) {
2011-03-13 09:23:43 +01:00
string currentPath = dirList [ idx ] ;
endPathWithSlash ( currentPath ) ;
string scenarioFile = currentPath + scenarioName + " / " + scenarioName + " .xml " ;
2010-03-18 22:26:40 +01:00
if ( fileExists ( scenarioFile ) = = true ) {
iIndex = idx ;
break ;
}
}
return iIndex ;
}
2011-01-20 16:56:30 +01:00
2010-03-20 13:11:46 +01:00
string Scenario : : getScenarioPath ( const vector < string > dirList , const string & scenarioName , bool getMatchingRootScenarioPathOnly ) {
2010-03-18 22:26:40 +01:00
string scenarioFile = " " ;
for ( int idx = 0 ; idx < dirList . size ( ) ; idx + + ) {
2011-03-13 09:23:43 +01:00
string currentPath = dirList [ idx ] ;
endPathWithSlash ( currentPath ) ;
scenarioFile = currentPath + scenarioName + " / " + scenarioName + " .xml " ;
2011-10-06 20:04:59 +02:00
//printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str());
2010-03-18 22:26:40 +01:00
if ( fileExists ( scenarioFile ) = = true ) {
2010-03-20 13:11:46 +01:00
if ( getMatchingRootScenarioPathOnly = = true ) {
scenarioFile = dirList [ idx ] ;
}
2010-03-18 22:26:40 +01:00
break ;
}
2010-03-20 13:11:46 +01:00
else {
scenarioFile = " " ;
}
2010-03-18 22:26:40 +01:00
}
2011-01-09 05:49:21 +01:00
2011-01-20 16:56:30 +01:00
return scenarioFile ;
}
2010-03-18 22:26:40 +01:00
string Scenario : : getScenarioPath ( const string & dir , const string & scenarioName ) {
2011-03-13 09:23:43 +01:00
string currentPath = dir ;
endPathWithSlash ( currentPath ) ;
string scenarioFile = currentPath + scenarioName + " / " + scenarioName + " .xml " ;
2010-03-18 22:26:40 +01:00
return scenarioFile ;
}
2011-01-20 16:56:30 +01:00
string Scenario : : getFunctionName ( const XmlNode * scriptNode ) {
string name = scriptNode - > getName ( ) ;
for ( int i = 0 ; i < scriptNode - > getAttributeCount ( ) ; + + i ) {
name + = " _ " + scriptNode - > getAttribute ( i ) - > getValue ( ) ;
}
return name ;
}
2011-10-06 20:04:59 +02:00
void Scenario : : loadScenarioInfo ( string file , ScenarioInfo * scenarioInfo ) {
//printf("[%s:%s] Line: %d file [%s]\n",__FILE__,__FUNCTION__,__LINE__,file.c_str());
Lang & lang = Lang : : getInstance ( ) ;
XmlTree xmlTree ;
xmlTree . load ( file , Properties : : getTagReplacementValues ( ) ) ;
const XmlNode * scenarioNode = xmlTree . getRootNode ( ) ;
const XmlNode * difficultyNode = scenarioNode - > getChild ( " difficulty " ) ;
scenarioInfo - > difficulty = difficultyNode - > getAttribute ( " value " ) - > getIntValue ( ) ;
if ( scenarioInfo - > difficulty < dVeryEasy | | scenarioInfo - > difficulty > dInsane ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " Invalid difficulty value specified in scenario: %d must be between %d and %d " , scenarioInfo - > difficulty , dVeryEasy , dInsane ) ;
throw std : : runtime_error ( szBuf ) ;
}
const XmlNode * playersNode = scenarioNode - > getChild ( " players " ) ;
for ( int i = 0 ; i < GameConstants : : maxPlayers ; + + i ) {
XmlNode * playerNode = NULL ;
string factionTypeName = " " ;
ControlType factionControl ;
if ( playersNode - > hasChildAtIndex ( " player " , i ) ) {
playerNode = playersNode - > getChild ( " player " , i ) ;
factionControl = strToControllerType ( playerNode - > getAttribute ( " control " ) - > getValue ( ) ) ;
2011-12-26 07:29:14 +01:00
if ( playerNode - > getAttribute ( " resource_multiplier " , false ) ! = NULL ) {
2011-10-06 20:04:59 +02:00
// if a multiplier exists use it
scenarioInfo - > resourceMultipliers [ i ] = playerNode - > getAttribute ( " resource_multiplier " ) - > getFloatValue ( ) ;
}
else {
// if no multiplier exists use defaults
scenarioInfo - > resourceMultipliers [ i ] = GameConstants : : normalMultiplier ;
if ( factionControl = = ctCpuEasy ) {
scenarioInfo - > resourceMultipliers [ i ] = GameConstants : : easyMultiplier ;
}
if ( factionControl = = ctCpuUltra ) {
scenarioInfo - > resourceMultipliers [ i ] = GameConstants : : ultraMultiplier ;
}
else if ( factionControl = = ctCpuMega ) {
scenarioInfo - > resourceMultipliers [ i ] = GameConstants : : megaMultiplier ;
}
}
}
else {
factionControl = ctClosed ;
}
scenarioInfo - > factionControls [ i ] = factionControl ;
if ( factionControl ! = ctClosed ) {
int teamIndex = playerNode - > getAttribute ( " team " ) - > getIntValue ( ) ;
if ( teamIndex < 1 | | teamIndex > GameConstants : : maxPlayers ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " Invalid team value specified in scenario: %d must be between %d and %d " , teamIndex , 1 , GameConstants : : maxPlayers ) ;
throw std : : runtime_error ( szBuf ) ;
}
scenarioInfo - > teams [ i ] = playerNode - > getAttribute ( " team " ) - > getIntValue ( ) ;
scenarioInfo - > factionTypeNames [ i ] = playerNode - > getAttribute ( " faction " ) - > getValue ( ) ;
}
scenarioInfo - > mapName = scenarioNode - > getChild ( " map " ) - > getAttribute ( " value " ) - > getValue ( ) ;
scenarioInfo - > tilesetName = scenarioNode - > getChild ( " tileset " ) - > getAttribute ( " value " ) - > getValue ( ) ;
scenarioInfo - > techTreeName = scenarioNode - > getChild ( " tech-tree " ) - > getAttribute ( " value " ) - > getValue ( ) ;
scenarioInfo - > defaultUnits = scenarioNode - > getChild ( " default-units " ) - > getAttribute ( " value " ) - > getBoolValue ( ) ;
scenarioInfo - > defaultResources = scenarioNode - > getChild ( " default-resources " ) - > getAttribute ( " value " ) - > getBoolValue ( ) ;
scenarioInfo - > defaultVictoryConditions = scenarioNode - > getChild ( " default-victory-conditions " ) - > getAttribute ( " value " ) - > getBoolValue ( ) ;
}
//add player info
scenarioInfo - > desc = lang . get ( " Player " ) + " : " ;
for ( int i = 0 ; i < GameConstants : : maxPlayers ; + + i ) {
if ( scenarioInfo - > factionControls [ i ] = = ctHuman ) {
scenarioInfo - > desc + = formatString ( scenarioInfo - > factionTypeNames [ i ] ) ;
break ;
}
}
//add misc info
string difficultyString = " Difficulty " + intToStr ( scenarioInfo - > difficulty ) ;
scenarioInfo - > desc + = " \n " ;
scenarioInfo - > desc + = lang . get ( " Difficulty " ) + " : " + lang . get ( difficultyString ) + " \n " ;
scenarioInfo - > desc + = lang . get ( " Map " ) + " : " + formatString ( scenarioInfo - > mapName ) + " \n " ;
scenarioInfo - > desc + = lang . get ( " Tileset " ) + " : " + formatString ( scenarioInfo - > tilesetName ) + " \n " ;
scenarioInfo - > desc + = lang . get ( " TechTree " ) + " : " + formatString ( scenarioInfo - > techTreeName ) + " \n " ;
if ( scenarioNode - > hasChild ( " fog-of-war " ) = = true ) {
if ( scenarioNode - > getChild ( " fog-of-war " ) - > getAttribute ( " value " ) - > getValue ( ) = = " explored " ) {
scenarioInfo - > fogOfWar = true ;
scenarioInfo - > fogOfWar_exploredFlag = true ;
}
else {
scenarioInfo - > fogOfWar = scenarioNode - > getChild ( " fog-of-war " ) - > getAttribute ( " value " ) - > getBoolValue ( ) ;
scenarioInfo - > fogOfWar_exploredFlag = false ;
}
//printf("\nFOG OF WAR is set to [%d]\n",scenarioInfo->fogOfWar);
}
else {
scenarioInfo - > fogOfWar = true ;
scenarioInfo - > fogOfWar_exploredFlag = false ;
}
scenarioInfo - > file = file ;
scenarioInfo - > name = extractFileFromDirectoryPath ( file ) ;
scenarioInfo - > name = cutLastExt ( scenarioInfo - > name ) ;
//scenarioLogoTexture = NULL;
//cleanupPreviewTexture();
//previewLoadDelayTimer=time(NULL);
//needToLoadTextures=true;
}
ControlType Scenario : : strToControllerType ( const string & str ) {
if ( str = = " closed " ) {
return ctClosed ;
}
else if ( str = = " cpu-easy " ) {
return ctCpuEasy ;
}
else if ( str = = " cpu " ) {
return ctCpu ;
}
else if ( str = = " cpu-ultra " ) {
return ctCpuUltra ;
}
else if ( str = = " cpu-mega " ) {
return ctCpuMega ;
}
else if ( str = = " human " ) {
return ctHuman ;
}
2011-12-26 07:29:14 +01:00
else if ( str = = " network " ) {
return ctNetwork ;
}
2011-10-06 20:04:59 +02:00
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " Invalid controller value specified in scenario: [%s] must be one of the following: closed, cpu-easy, cpu, cpu-ultra, cpu-mega, human " , str . c_str ( ) ) ;
throw std : : runtime_error ( szBuf ) ;
}
void Scenario : : loadGameSettings ( const vector < string > & dirList , const ScenarioInfo * scenarioInfo , GameSettings * gameSettings , string scenarioDescription ) {
// if(listBoxScenario.getSelectedItemIndex() < 0) {
// char szBuf[1024]="";
// sprintf(szBuf,"listBoxScenario.getSelectedItemIndex() < 0, = %d",listBoxScenario.getSelectedItemIndex());
// throw runtime_error(szBuf);
// }
// else if(listBoxScenario.getSelectedItemIndex() >= scenarioFiles.size()) {
// char szBuf[1024]="";
// sprintf(szBuf,"listBoxScenario.getSelectedItemIndex() >= scenarioFiles.size(), = [%d][%d]",listBoxScenario.getSelectedItemIndex(),(int)scenarioFiles.size());
// throw runtime_error(szBuf);
// }
int factionCount = 0 ;
//printf("\n\n\n$$$$$$$$$$$$$ [%s]\n\n\n",scenarioFiles[listBoxScenario.getSelectedItemIndex()].c_str());
//gameSettings->setDescription(formatString(scenarioFiles[listBoxScenario.getSelectedItemIndex()]));
gameSettings - > setDescription ( scenarioDescription ) ;
gameSettings - > setMap ( scenarioInfo - > mapName ) ;
gameSettings - > setTileset ( scenarioInfo - > tilesetName ) ;
gameSettings - > setTech ( scenarioInfo - > techTreeName ) ;
//gameSettings->setScenario(scenarioFiles[listBoxScenario.getSelectedItemIndex()]);
gameSettings - > setScenario ( scenarioInfo - > name ) ;
//gameSettings->setScenarioDir(Scenario::getScenarioPath(dirList, scenarioFiles[listBoxScenario.getSelectedItemIndex()]));
gameSettings - > setScenarioDir ( Scenario : : getScenarioPath ( dirList , scenarioInfo - > name ) ) ;
gameSettings - > setDefaultUnits ( scenarioInfo - > defaultUnits ) ;
gameSettings - > setDefaultResources ( scenarioInfo - > defaultResources ) ;
gameSettings - > setDefaultVictoryConditions ( scenarioInfo - > defaultVictoryConditions ) ;
for ( int i = 0 ; i < GameConstants : : maxPlayers ; + + i ) {
ControlType ct = static_cast < ControlType > ( scenarioInfo - > factionControls [ i ] ) ;
if ( ct ! = ctClosed ) {
if ( ct = = ctHuman ) {
gameSettings - > setThisFactionIndex ( factionCount ) ;
}
gameSettings - > setFactionControl ( factionCount , ct ) ;
gameSettings - > setResourceMultiplierIndex ( factionCount , ( scenarioInfo - > resourceMultipliers [ i ] - 0.5f ) / 0.1f ) ;
gameSettings - > setTeam ( factionCount , scenarioInfo - > teams [ i ] - 1 ) ;
gameSettings - > setStartLocationIndex ( factionCount , i ) ;
gameSettings - > setFactionTypeName ( factionCount , scenarioInfo - > factionTypeNames [ i ] ) ;
factionCount + + ;
}
}
gameSettings - > setFactionCount ( factionCount ) ;
gameSettings - > setFogOfWar ( scenarioInfo - > fogOfWar ) ;
uint32 valueFlags1 = gameSettings - > getFlagTypes1 ( ) ;
if ( scenarioInfo - > fogOfWar = = false | | scenarioInfo - > fogOfWar_exploredFlag ) {
valueFlags1 | = ft1_show_map_resources ;
gameSettings - > setFlagTypes1 ( valueFlags1 ) ;
}
else {
valueFlags1 & = ~ ft1_show_map_resources ;
gameSettings - > setFlagTypes1 ( valueFlags1 ) ;
}
gameSettings - > setPathFinderType ( static_cast < PathFinderType > ( Config : : getInstance ( ) . getInt ( " ScenarioPathFinderType " , intToStr ( pfBasic ) . c_str ( ) ) ) ) ;
}
2011-01-20 16:56:30 +01:00
} } //end namespace