// ============================================================== // 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 #include "logger.h" #include "xml_parser.h" #include "util.h" #include "game_util.h" #include #include "platform_common.h" #include "properties.h" #include "lang.h" #include "config.h" #include "leak_dumper.h" using namespace Shared::Xml; using namespace Shared::Util; using namespace Shared::PlatformCommon; using namespace std; namespace Glest{ namespace Game{ // ===================================================== // class Scenario // ===================================================== Scenario::~Scenario() { } Checksum Scenario::load(const string &path) { //printf("[%s:%s] Line: %d path [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str()); Checksum scenarioChecksum; try { scenarioChecksum.addFile(path); checksumValue.addFile(path); string name= cutLastExt(lastDir(path)); Logger::getInstance().add("Scenario: " + formatString(name), true); Scenario::loadScenarioInfo(path, &info); //parse xml XmlTree xmlTree; xmlTree.load(path,Properties::getTagReplacementValues()); const XmlNode *scenarioNode= xmlTree.getRootNode(); const XmlNode *scriptsNode= scenarioNode->getChild("scripts"); for(int i= 0; igetChildCount(); ++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()); } return scenarioChecksum; } int Scenario::getScenarioPathIndex(const vector dirList, const string &scenarioName) { int iIndex = 0; for(int idx = 0; idx < dirList.size(); idx++) { string currentPath = dirList[idx]; endPathWithSlash(currentPath); string scenarioFile = currentPath + scenarioName + "/" + scenarioName + ".xml"; if(fileExists(scenarioFile) == true) { iIndex = idx; break; } } return iIndex; } string Scenario::getScenarioPath(const vector dirList, const string &scenarioName, bool getMatchingRootScenarioPathOnly){ string scenarioFile = ""; for(int idx = 0; idx < dirList.size(); idx++) { string currentPath = dirList[idx]; endPathWithSlash(currentPath); scenarioFile = currentPath + scenarioName + "/" + scenarioName + ".xml"; //printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str()); if(fileExists(scenarioFile) == true) { if(getMatchingRootScenarioPathOnly == true) { scenarioFile = dirList[idx]; } break; } else { scenarioFile = ""; } } return scenarioFile; } string Scenario::getScenarioPath(const string &dir, const string &scenarioName){ string currentPath = dir; endPathWithSlash(currentPath); string scenarioFile = currentPath + scenarioName + "/" + scenarioName + ".xml"; return scenarioFile; } string Scenario::getFunctionName(const XmlNode *scriptNode){ string name= scriptNode->getName(); for(int i= 0; igetAttributeCount(); ++i){ name+= "_" + scriptNode->getAttribute(i)->getValue(); } return name; } 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() ); if(playerNode->getAttribute("resource_multiplier",false)!=NULL) { // 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; ifactionControls[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; } 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 &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(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(Config::getInstance().getInt("ScenarioPathFinderType",intToStr(pfBasic).c_str()))); } }}//end namespace