mirror of
https://github.com/glest/glest-source.git
synced 2025-02-24 11:42:31 +01:00
716 lines
23 KiB
C++
716 lines
23 KiB
C++
//
|
|
// scenario.cpp:
|
|
//
|
|
// This file is part of ZetaGlest <https://github.com/ZetaGlest>
|
|
//
|
|
// Copyright (C) 2018 The ZetaGlest team
|
|
//
|
|
// ZetaGlest is a fork of MegaGlest <https://megaglest.org>
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
|
|
#include "scenario.h"
|
|
|
|
#include <stdexcept>
|
|
#include "logger.h"
|
|
#include "xml_parser.h"
|
|
#include "util.h"
|
|
#include "game_util.h"
|
|
#include <stdio.h>
|
|
#include "platform_common.h"
|
|
#include "properties.h"
|
|
#include "lang.h"
|
|
#include "socket.h"
|
|
#include "config.h"
|
|
#include "platform_util.h"
|
|
#include "gen_uuid.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));
|
|
|
|
char szBuf[8096] = "";
|
|
snprintf(szBuf, 8096,
|
|
Lang::getInstance().getString("LogScreenGameLoadingScenario", "").c_str(), formatString(name).c_str());
|
|
Logger::getInstance().add(szBuf, true);
|
|
|
|
bool isTutorial = Scenario::isGameTutorial(path);
|
|
|
|
//Properties::setTechtreePath();
|
|
|
|
//printf("path [%s]\n",path.c_str());
|
|
string scenarioFolder = cutLastFile(formatPath(path));
|
|
endPathWithSlash(scenarioFolder);
|
|
|
|
if (isTutorial == false) {
|
|
Properties::setScenarioPath(scenarioFolder);
|
|
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED)
|
|
printf("==> Set scenario path to [%s]\n",
|
|
scenarioFolder.c_str());
|
|
} else {
|
|
Properties::setTutorialPath(scenarioFolder);
|
|
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED)
|
|
printf("==> Set tutorial path to [%s]\n",
|
|
scenarioFolder.c_str());
|
|
}
|
|
|
|
Scenario::loadScenarioInfo(path, &info, isTutorial);
|
|
|
|
//parse xml
|
|
XmlTree xmlTree;
|
|
xmlTree.setSkipUpdatePathClimbingParts(true);
|
|
xmlTree.load(path, Properties::getTagReplacementValues());
|
|
const XmlNode *scenarioNode = xmlTree.getRootNode();
|
|
const XmlNode *scriptsNode = scenarioNode->getChild("scripts");
|
|
|
|
for (int i = 0; i < (int) 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 & ex) {
|
|
char szBuf[8096] = "";
|
|
snprintf(szBuf, 8096,
|
|
"In [%s::%s %d]\nError loading scenario [%s]:\n%s\n",
|
|
extractFileFromDirectoryPath(__FILE__).c_str(),
|
|
__FUNCTION__, __LINE__, path.c_str(), ex.what());
|
|
SystemFlags::OutputDebug(SystemFlags::debugError, szBuf);
|
|
if (SystemFlags::
|
|
getSystemSettingType(SystemFlags::debugSystem).enabled)
|
|
SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf);
|
|
|
|
throw megaglest_runtime_error(szBuf);
|
|
}
|
|
|
|
return scenarioChecksum;
|
|
}
|
|
|
|
int Scenario::getScenarioPathIndex(const vector < string > dirList,
|
|
const string & scenarioName) {
|
|
int iIndex = 0;
|
|
for (int idx = 0; idx < (int) 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::getScenarioDir(const vector < string > dir,
|
|
const string & scenarioName) {
|
|
string scenarioDir = "";
|
|
for (int idx = 0; idx < (int) dir.size(); idx++) {
|
|
string currentPath = dir[idx];
|
|
endPathWithSlash(currentPath);
|
|
string 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) {
|
|
scenarioDir = currentPath + scenarioName + "/";
|
|
break;
|
|
}
|
|
}
|
|
|
|
return scenarioDir;
|
|
}
|
|
|
|
string Scenario::getScenarioPath(const vector < string > dirList,
|
|
const string & scenarioName,
|
|
bool getMatchingRootScenarioPathOnly) {
|
|
string scenarioFile = "";
|
|
for (int idx = 0; idx < (int) 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 (SystemFlags::VERBOSE_MODE_ENABLED)
|
|
printf
|
|
("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",
|
|
__FILE__, __FUNCTION__, __LINE__, scenarioName.c_str(),
|
|
scenarioFile.c_str());
|
|
//printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str());
|
|
|
|
if (fileExists(scenarioFile) == true) {
|
|
//printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str());
|
|
|
|
if (getMatchingRootScenarioPathOnly == true) {
|
|
//printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str());
|
|
scenarioFile = dirList[idx];
|
|
}
|
|
break;
|
|
} else {
|
|
//printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str());
|
|
scenarioFile = "";
|
|
}
|
|
}
|
|
//printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str());
|
|
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; i < (int) scriptNode->getAttributeCount(); ++i) {
|
|
name += "_" + scriptNode->getAttribute(i)->getValue();
|
|
}
|
|
return name;
|
|
}
|
|
|
|
bool Scenario::isGameTutorial(string path) {
|
|
bool isTutorial = false;
|
|
Config & config = Config::getInstance();
|
|
vector < string > tutorialPaths =
|
|
config.getPathListForType(ptTutorials);
|
|
if (tutorialPaths.empty() == false) {
|
|
for (unsigned int tutorialIndex = 0;
|
|
tutorialIndex < tutorialPaths.size(); ++tutorialIndex) {
|
|
const string & tutorialPath = tutorialPaths[tutorialIndex];
|
|
size_t pos = path.find(tutorialPath);
|
|
if (pos != path.npos) {
|
|
isTutorial = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return isTutorial;
|
|
}
|
|
|
|
bool Scenario::loadScenarioInfo(string file,
|
|
ScenarioInfo * scenarioInfo,
|
|
bool isTutorial) {
|
|
if (fileExists(file) == false) {
|
|
// FIXME: A new string will need a new translation; we haven't
|
|
// discussed how we'll deal with translations yet.
|
|
//
|
|
// this particular string is just a placeholder, and will hopefully
|
|
// get changed soon, when we can point a user to complete documentation
|
|
// on how to obtain a scenario
|
|
// -andy5995 2018-02-01
|
|
scenarioInfo->desc = "This scenario will be available soon.\n\n\
|
|
Please contact the ZetaGlest team for more info.";
|
|
|
|
scenarioInfo->name = file;
|
|
return false;
|
|
}
|
|
|
|
//printf("[%s:%s] Line: %d file [%s]\n",__FILE__,__FUNCTION__,__LINE__,file.c_str());
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED)
|
|
printf("In [%s::%s Line: %d] file [%s]\n",
|
|
extractFileFromDirectoryPath(__FILE__).c_str(),
|
|
__FUNCTION__, __LINE__, file.c_str());
|
|
//printf("In [%s::%s Line: %d] file [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,file.c_str());
|
|
|
|
//printf("[%s:%s] Line: %d file [%s]\n",__FILE__,__FUNCTION__,__LINE__,file.c_str());
|
|
Lang & lang = Lang::getInstance();
|
|
string scenarioDir = cutLastFile(formatPath(file));
|
|
string scenarioName = extractLastDirectoryFromPath(scenarioDir);
|
|
scenarioDir = cutLastFile(scenarioDir);
|
|
//printf("[%s:%s] Line: %d scenarioDir [%s] scenarioName [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioDir.c_str(),scenarioName.c_str());
|
|
|
|
XmlTree xmlTree;
|
|
xmlTree.load(file, Properties::getTagReplacementValues());
|
|
|
|
const XmlNode *scenarioNode = xmlTree.getRootNode();
|
|
if (scenarioNode == NULL) {
|
|
char szBuf[8096] = "";
|
|
snprintf(szBuf, 8096, "scenarioNode == NULL for file [%s]\n",
|
|
file.c_str());
|
|
throw std::runtime_error(szBuf);
|
|
}
|
|
const XmlNode *difficultyNode = scenarioNode->getChild("difficulty");
|
|
if (difficultyNode == NULL) {
|
|
char szBuf[8096] = "";
|
|
snprintf(szBuf, 8096, "difficultyNode == NULL for file [%s]\n",
|
|
file.c_str());
|
|
throw std::runtime_error(szBuf);
|
|
}
|
|
|
|
scenarioInfo->difficulty =
|
|
difficultyNode->getAttribute("value")->getIntValue();
|
|
if (scenarioInfo->difficulty < dVeryEasy
|
|
|| scenarioInfo->difficulty > dInsane) {
|
|
char szBuf[8096] = "";
|
|
snprintf(szBuf, 8096,
|
|
"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");
|
|
if (playersNode == NULL) {
|
|
char szBuf[8096] = "";
|
|
snprintf(szBuf, 8096, "playersNode == NULL for file [%s]\n",
|
|
file.c_str());
|
|
throw std::runtime_error(szBuf);
|
|
}
|
|
|
|
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);
|
|
if (playerNode == NULL) {
|
|
char szBuf[8096] = "";
|
|
snprintf(szBuf, 8096,
|
|
"playerNode == NULL for index = %d for file [%s]\n",
|
|
i, file.c_str());
|
|
throw std::runtime_error(szBuf);
|
|
}
|
|
|
|
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 == ctCpuZeta) {
|
|
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 + GameConstants::specialFactions) {
|
|
char szBuf[8096] = "";
|
|
snprintf(szBuf, 8096,
|
|
"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] = teamIndex;
|
|
scenarioInfo->factionTypeNames[i] =
|
|
playerNode->getAttribute("faction")->getValue();
|
|
} else {
|
|
scenarioInfo->teams[i] = 0;
|
|
scenarioInfo->factionTypeNames[i] = "";
|
|
}
|
|
|
|
if (scenarioNode->getChild("map") == NULL) {
|
|
char szBuf[8096] = "";
|
|
snprintf(szBuf, 8096, "map == NULL for file [%s]\n",
|
|
file.c_str());
|
|
throw std::runtime_error(szBuf);
|
|
}
|
|
if (scenarioNode->getChild("tileset") == NULL) {
|
|
char szBuf[8096] = "";
|
|
snprintf(szBuf, 8096, "tileset == NULL for file [%s]\n",
|
|
file.c_str());
|
|
throw std::runtime_error(szBuf);
|
|
}
|
|
if (scenarioNode->getChild("tech-tree") == NULL) {
|
|
char szBuf[8096] = "";
|
|
snprintf(szBuf, 8096, "tech-tree == NULL for file [%s]\n",
|
|
file.c_str());
|
|
throw std::runtime_error(szBuf);
|
|
}
|
|
if (scenarioNode->getChild("default-units") == NULL) {
|
|
char szBuf[8096] = "";
|
|
snprintf(szBuf, 8096, "default-units == NULL for file [%s]\n",
|
|
file.c_str());
|
|
throw std::runtime_error(szBuf);
|
|
}
|
|
if (scenarioNode->getChild("default-resources") == NULL) {
|
|
char szBuf[8096] = "";
|
|
snprintf(szBuf, 8096,
|
|
"default-resources == NULL for file [%s]\n",
|
|
file.c_str());
|
|
throw std::runtime_error(szBuf);
|
|
}
|
|
if (scenarioNode->getChild("default-victory-conditions") == NULL) {
|
|
char szBuf[8096] = "";
|
|
snprintf(szBuf, 8096,
|
|
"default-victory-conditions == NULL for file [%s]\n",
|
|
file.c_str());
|
|
throw std::runtime_error(szBuf);
|
|
}
|
|
|
|
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.getString("PlayerFaction") + ": ";
|
|
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.getString("Difficulty") + ": " +
|
|
lang.getString(difficultyString) + "\n";
|
|
scenarioInfo->desc +=
|
|
lang.getString("Map") + ": " +
|
|
formatString(scenarioInfo->mapName) + "\n";
|
|
scenarioInfo->desc +=
|
|
lang.getString("Tileset") + ": " +
|
|
formatString(scenarioInfo->tilesetName) + "\n";
|
|
scenarioInfo->desc +=
|
|
lang.getString("TechTree") + ": " +
|
|
formatString(scenarioInfo->techTreeName) + "\n";
|
|
|
|
|
|
//look for description and append it
|
|
lang.loadScenarioStrings(scenarioDir, scenarioName.c_str(),
|
|
isTutorial);
|
|
//string tmp_description = lang.getScenarioString("DESCRIPTION");
|
|
string tmp_description = "";
|
|
if (lang.hasScenarioString("DESCRIPTION") == true) {
|
|
tmp_description = lang.getScenarioString("DESCRIPTION");
|
|
}
|
|
if (tmp_description != "") {
|
|
scenarioInfo->desc +=
|
|
lang.getString("Description") + ": \n" + tmp_description +
|
|
"\n";
|
|
}
|
|
|
|
scenarioInfo->namei18n = "";
|
|
if (lang.hasScenarioString("SCENARIO_NAME") == true) {
|
|
scenarioInfo->namei18n = lang.getScenarioString("SCENARIO_NAME");
|
|
//printf("scenarioInfo->namei18n [%s]\n",scenarioInfo->namei18n.c_str());
|
|
} else if (lang.hasScenarioString("TUTORIAL_NAME") == true) {
|
|
scenarioInfo->namei18n = lang.getScenarioString("TUTORIAL_NAME");
|
|
//printf("scenarioInfo->namei18n [%s]\n",scenarioInfo->namei18n.c_str());
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
if (scenarioNode->hasChild("shared-team-units") == true) {
|
|
scenarioInfo->allowTeamUnitSharing =
|
|
scenarioNode->
|
|
getChild("shared-team-units")->getAttribute("value")->
|
|
getBoolValue();
|
|
//printf("\nallowTeamUnitSharing is set to [%s]\n",scenarioInfo->allowTeamUnitSharing);
|
|
} else {
|
|
scenarioInfo->allowTeamUnitSharing = false;
|
|
}
|
|
|
|
if (scenarioNode->hasChild("shared-team-resources") == true) {
|
|
scenarioInfo->allowTeamResourceSharing =
|
|
scenarioNode->
|
|
getChild("shared-team-resources")->getAttribute("value")->
|
|
getBoolValue();
|
|
//printf("\nallowTeamResourceSharing is set to [%s]\n",scenarioInfo->allowTeamResourceSharing);
|
|
} else {
|
|
scenarioInfo->allowTeamResourceSharing = false;
|
|
}
|
|
|
|
scenarioInfo->file = file;
|
|
scenarioInfo->name = extractFileFromDirectoryPath(file);
|
|
scenarioInfo->name = cutLastExt(scenarioInfo->name);
|
|
|
|
return true;
|
|
|
|
//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" || str == "cpu-zeta") {
|
|
return ctCpuZeta;
|
|
} else if (str == "human") {
|
|
return ctHuman;
|
|
} else if (str == "network") {
|
|
return ctNetwork;
|
|
}
|
|
|
|
char szBuf[8096] = "";
|
|
snprintf(szBuf, 8096,
|
|
"Invalid controller value specified in scenario: [%s] must be one of the following: closed, cpu-easy, cpu, cpu-ultra, cpu-zeta, human",
|
|
str.c_str());
|
|
throw std::runtime_error(szBuf);
|
|
}
|
|
|
|
string Scenario::controllerTypeToStr(const ControlType & ct) {
|
|
string controlString = "";
|
|
|
|
Lang & lang = Lang::getInstance();
|
|
switch (ct) {
|
|
case ctCpuEasy:
|
|
controlString = lang.getString("CpuEasy");
|
|
break;
|
|
case ctCpu:
|
|
controlString = lang.getString("Cpu");
|
|
break;
|
|
case ctCpuUltra:
|
|
controlString = lang.getString("CpuUltra");
|
|
break;
|
|
case ctCpuZeta:
|
|
controlString = lang.getString("CpuZeta");
|
|
break;
|
|
case ctNetwork:
|
|
controlString = lang.getString("Network");
|
|
break;
|
|
case ctHuman:
|
|
controlString = lang.getString("Human");
|
|
break;
|
|
|
|
case ctNetworkCpuEasy:
|
|
controlString = lang.getString("NetworkCpuEasy");
|
|
break;
|
|
case ctNetworkCpu:
|
|
controlString = lang.getString("NetworkCpu");
|
|
break;
|
|
case ctNetworkCpuUltra:
|
|
controlString = lang.getString("NetworkCpuUltra");
|
|
break;
|
|
case ctNetworkCpuZeta:
|
|
controlString = lang.getString("NetworkCpuZeta");
|
|
break;
|
|
|
|
default:
|
|
printf("Error control = %d\n", ct);
|
|
//assert(false);
|
|
break;
|
|
}
|
|
|
|
return controlString;
|
|
}
|
|
|
|
void Scenario::loadGameSettings(const vector < string > &dirList,
|
|
const ScenarioInfo * scenarioInfo,
|
|
GameSettings * gameSettings,
|
|
string scenarioDescription) {
|
|
int factionCount = 0;
|
|
int AIPlayerCount = 0;
|
|
Lang & lang = Lang::getInstance();
|
|
|
|
if (gameSettings->getGameUUID() == "") {
|
|
gameSettings->setGameUUID(getUUIDAsString());
|
|
}
|
|
|
|
gameSettings->setDescription(scenarioDescription);
|
|
gameSettings->setMap(scenarioInfo->mapName);
|
|
gameSettings->setTileset(scenarioInfo->tilesetName);
|
|
gameSettings->setTech(scenarioInfo->techTreeName);
|
|
gameSettings->setScenario(scenarioInfo->name);
|
|
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);
|
|
|
|
if (gameSettings->getNetworkPlayerName(factionCount) == "") {
|
|
gameSettings->setNetworkPlayerName(factionCount,
|
|
Config::
|
|
getInstance().getString
|
|
("NetPlayerName",
|
|
Socket::getHostName
|
|
().c_str()));
|
|
}
|
|
gameSettings->setNetworkPlayerUUID(factionCount,
|
|
Config::
|
|
getInstance().getString
|
|
("PlayerId", ""));
|
|
gameSettings->setNetworkPlayerPlatform(factionCount,
|
|
getPlatformNameString
|
|
());
|
|
} else if (ct == ctNetwork || ct == ctNetworkUnassigned) {
|
|
if (gameSettings->getNetworkPlayerName(factionCount) == "") {
|
|
gameSettings->setNetworkPlayerName(factionCount,
|
|
controllerTypeToStr(ct));
|
|
}
|
|
} else { //this is a CPU player
|
|
AIPlayerCount++;
|
|
if (gameSettings->getNetworkPlayerName(factionCount) == "") {
|
|
gameSettings->setNetworkPlayerName(factionCount,
|
|
lang.getString("AI") +
|
|
intToStr(AIPlayerCount));
|
|
}
|
|
}
|
|
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);
|
|
}
|
|
|
|
if (scenarioInfo->allowTeamUnitSharing == true) {
|
|
valueFlags1 |= ft1_allow_shared_team_units;
|
|
gameSettings->setFlagTypes1(valueFlags1);
|
|
} else {
|
|
valueFlags1 &= ~ft1_allow_shared_team_units;
|
|
gameSettings->setFlagTypes1(valueFlags1);
|
|
}
|
|
|
|
if (scenarioInfo->allowTeamResourceSharing == true) {
|
|
valueFlags1 |= ft1_allow_shared_team_resources;
|
|
gameSettings->setFlagTypes1(valueFlags1);
|
|
} else {
|
|
valueFlags1 &= ~ft1_allow_shared_team_resources;
|
|
gameSettings->setFlagTypes1(valueFlags1);
|
|
}
|
|
|
|
gameSettings->setPathFinderType(static_cast <PathFinderType>
|
|
(Config::
|
|
getInstance().getInt
|
|
("ScenarioPathFinderType",
|
|
intToStr(pfBasic).c_str())));
|
|
}
|
|
|
|
|
|
}
|
|
} //end namespace
|