- initial loading logic for loading of saved games.

- currently we always save the game during out of synch or on game quit.
- added a new commandline option to load the last saved game, this doesn't do much yet, just creates units in the map locations they were when the game was saved
./megaglest --load-saved-game
This commit is contained in:
Mark Vejvoda 2012-03-12 23:08:22 +00:00
parent 6e857b3af2
commit 9271d7d7f6
25 changed files with 972 additions and 97 deletions

View File

@ -111,6 +111,7 @@ Game::Game() : ProgramState(NULL) {
currentAmbientSound=NULL;
//printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
loadGameNode = NULL;
lastNetworkPlayerConnectionCheck = time(NULL);
fadeMusicMilliseconds = Config::getInstance().getInt("GameStartStopFadeSoundMilliseconds",intToStr(fadeMusicMilliseconds).c_str());
@ -184,6 +185,8 @@ void Game::resetMembers() {
currentAmbientSound=NULL;
//printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound);
loadGameNode = NULL;
lastNetworkPlayerConnectionCheck = time(NULL);
fadeMusicMilliseconds = Config::getInstance().getInt("GameStartStopFadeSoundMilliseconds",intToStr(fadeMusicMilliseconds).c_str());
@ -843,6 +846,9 @@ void Game::init(bool initForPreviewOnly) {
}
world.init(this, gameSettings.getDefaultUnits());
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__);
@ -3493,6 +3499,7 @@ void Game::saveGame(string name) {
weatherParticleSystem->saveGame(gameNode);
}
//GameSettings gameSettings;
gameSettings.saveGame(gameNode);
//Vec2i lastMousePos;
gameNode->addAttribute("lastMousePos",lastMousePos.getString(), mapTagReplacements);
//time_t lastRenderLog2d;
@ -3574,4 +3581,45 @@ void Game::saveGame(string name) {
xmlTree.save(saveGameFile);
}
void Game::loadGame(string name,Program *programPtr,bool isMasterserverMode) {
XmlTree xmlTree;
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();
//const XmlNode *versionNode= rootNode->getChild("megaglest-saved-game");
const XmlNode *versionNode= rootNode;
string gameVer = versionNode->getAttribute("version")->getValue();
if(gameVer != glestVersionString) {
char szBuf[4096]="";
sprintf(szBuf,"saved game version does match your application version: [%s] --> [%s]",gameVer.c_str(),glestVersionString.c_str());
throw runtime_error(szBuf);
}
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;
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, &newGameSettings, isMasterserverMode);
newGame->loadGameNode = 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

View File

@ -149,6 +149,8 @@ private:
time_t lastMasterServerGameStatsDump;
XmlNode *loadGameNode;
public:
Game();
Game(Program *program, const GameSettings *gameSettings, bool masterserverMode);
@ -226,6 +228,7 @@ public:
void endGame();
void saveGame(string name);
static void loadGame(string name,Program *programPtr,bool isMasterserverMode);
private:
//render

View File

@ -15,9 +15,11 @@
#include "game_constants.h"
#include "conversion.h"
#include <algorithm>
#include "xml_parser.h"
#include "leak_dumper.h"
using namespace Shared::Util;
using Shared::Xml::XmlNode;
namespace Glest{ namespace Game{
@ -292,6 +294,234 @@ public:
return result;
}
void saveGame(XmlNode *rootNode) const {
std::map<string,string> mapTagReplacements;
XmlNode *gameSettingsNode = rootNode->addChild("GameSettings");
// string description;
gameSettingsNode->addAttribute("description",description, mapTagReplacements);
// string map;
gameSettingsNode->addAttribute("map",map, mapTagReplacements);
// string tileset;
gameSettingsNode->addAttribute("tileset",tileset, mapTagReplacements);
// string tech;
gameSettingsNode->addAttribute("tech",tech, mapTagReplacements);
// string scenario;
gameSettingsNode->addAttribute("scenario",scenario, mapTagReplacements);
// string scenarioDir;
gameSettingsNode->addAttribute("scenarioDir",scenarioDir, mapTagReplacements);
// string factionTypeNames[GameConstants::maxPlayers]; //faction names
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
XmlNode *factionTypeNamesNode = gameSettingsNode->addChild("factionTypeNames");
factionTypeNamesNode->addAttribute("name",factionTypeNames[idx], mapTagReplacements);
}
// string networkPlayerNames[GameConstants::maxPlayers];
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
XmlNode *networkPlayerNamesNode = gameSettingsNode->addChild("networkPlayerNames");
networkPlayerNamesNode->addAttribute("name",networkPlayerNames[idx], mapTagReplacements);
}
// int networkPlayerStatuses[GameConstants::maxPlayers];
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
XmlNode *networkPlayerStatusesNode = gameSettingsNode->addChild("networkPlayerStatuses");
networkPlayerStatusesNode->addAttribute("status",intToStr(networkPlayerStatuses[idx]), mapTagReplacements);
}
// string networkPlayerLanguages[GameConstants::maxPlayers];
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
XmlNode *networkPlayerLanguagesNode = gameSettingsNode->addChild("networkPlayerLanguages");
networkPlayerLanguagesNode->addAttribute("name",networkPlayerLanguages[idx], mapTagReplacements);
}
// ControlType factionControls[GameConstants::maxPlayers];
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
XmlNode *factionControlsNode = gameSettingsNode->addChild("factionControls");
factionControlsNode->addAttribute("control",intToStr(factionControls[idx]), mapTagReplacements);
}
// int resourceMultiplierIndex[GameConstants::maxPlayers];
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
XmlNode *resourceMultiplierIndexNode = gameSettingsNode->addChild("resourceMultiplierIndex");
resourceMultiplierIndexNode->addAttribute("multiplier",intToStr(resourceMultiplierIndex[idx]), mapTagReplacements);
}
// int thisFactionIndex;
gameSettingsNode->addAttribute("thisFactionIndex",intToStr(thisFactionIndex), mapTagReplacements);
// int factionCount;
gameSettingsNode->addAttribute("factionCount",intToStr(factionCount), mapTagReplacements);
// int teams[GameConstants::maxPlayers];
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
XmlNode *teamsNode = gameSettingsNode->addChild("teams");
teamsNode->addAttribute("team",intToStr(teams[idx]), mapTagReplacements);
}
// int startLocationIndex[GameConstants::maxPlayers];
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
XmlNode *startLocationIndexNode = gameSettingsNode->addChild("startLocationIndex");
startLocationIndexNode->addAttribute("location",intToStr(startLocationIndex[idx]), mapTagReplacements);
}
// int mapFilterIndex;
gameSettingsNode->addAttribute("mapFilterIndex",intToStr(mapFilterIndex), mapTagReplacements);
//
//
// bool defaultUnits;
gameSettingsNode->addAttribute("defaultUnits",intToStr(defaultUnits), mapTagReplacements);
// bool defaultResources;
gameSettingsNode->addAttribute("defaultResources",intToStr(defaultResources), mapTagReplacements);
// bool defaultVictoryConditions;
gameSettingsNode->addAttribute("defaultVictoryConditions",intToStr(defaultVictoryConditions), mapTagReplacements);
// bool fogOfWar;
gameSettingsNode->addAttribute("fogOfWar",intToStr(fogOfWar), mapTagReplacements);
// bool allowObservers;
gameSettingsNode->addAttribute("allowObservers",intToStr(allowObservers), mapTagReplacements);
// bool enableObserverModeAtEndGame;
gameSettingsNode->addAttribute("enableObserverModeAtEndGame",intToStr(enableObserverModeAtEndGame), mapTagReplacements);
// bool enableServerControlledAI;
gameSettingsNode->addAttribute("enableServerControlledAI",intToStr(enableServerControlledAI), mapTagReplacements);
// int networkFramePeriod;
gameSettingsNode->addAttribute("networkFramePeriod",intToStr(networkFramePeriod), mapTagReplacements);
// bool networkPauseGameForLaggedClients;
gameSettingsNode->addAttribute("networkPauseGameForLaggedClients",intToStr(networkPauseGameForLaggedClients), mapTagReplacements);
// PathFinderType pathFinderType;
gameSettingsNode->addAttribute("pathFinderType",intToStr(pathFinderType), mapTagReplacements);
// uint32 flagTypes1;
gameSettingsNode->addAttribute("flagTypes1",intToStr(flagTypes1), mapTagReplacements);
// int32 mapCRC;
gameSettingsNode->addAttribute("mapCRC",intToStr(mapCRC), mapTagReplacements);
// int32 tilesetCRC;
gameSettingsNode->addAttribute("tilesetCRC",intToStr(tilesetCRC), mapTagReplacements);
// int32 techCRC;
gameSettingsNode->addAttribute("techCRC",intToStr(techCRC), mapTagReplacements);
// vector<pair<string,int32> > factionCRCList;
for(unsigned int i = 0; i < factionCRCList.size(); ++i) {
const pair<string,int32> &item = factionCRCList[i];
XmlNode *factionCRCListNode = gameSettingsNode->addChild("factionCRCList");
factionCRCListNode->addAttribute("key",item.first, mapTagReplacements);
factionCRCListNode->addAttribute("value",intToStr(item.second), mapTagReplacements);
}
// int aiAcceptSwitchTeamPercentChance;
gameSettingsNode->addAttribute("aiAcceptSwitchTeamPercentChance",intToStr(aiAcceptSwitchTeamPercentChance), mapTagReplacements);
// int masterserver_admin;
gameSettingsNode->addAttribute("masterserver_admin",intToStr(masterserver_admin), mapTagReplacements);
}
void loadGame(const XmlNode *rootNode) {
const XmlNode *gameSettingsNode = rootNode->getChild("GameSettings");
// string description;
description = gameSettingsNode->getAttribute("description")->getValue();
// string map;
map = gameSettingsNode->getAttribute("map")->getValue();
// string tileset;
tileset = gameSettingsNode->getAttribute("tileset")->getValue();
// string tech;
tech = gameSettingsNode->getAttribute("tech")->getValue();
// string scenario;
scenario = gameSettingsNode->getAttribute("scenario")->getValue();
// string scenarioDir;
scenarioDir = gameSettingsNode->getAttribute("scenarioDir")->getValue();
// string factionTypeNames[GameConstants::maxPlayers]; //faction names
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
const XmlNode *factionTypeNamesNode = gameSettingsNode->getChild("factionTypeNames",idx);
factionTypeNames[idx] = factionTypeNamesNode->getAttribute("name")->getValue();
}
// string networkPlayerNames[GameConstants::maxPlayers];
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
const XmlNode *networkPlayerNamesNode = gameSettingsNode->getChild("networkPlayerNames",idx);
networkPlayerNames[idx] = networkPlayerNamesNode->getAttribute("name")->getValue();
}
// int networkPlayerStatuses[GameConstants::maxPlayers];
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
const XmlNode *networkPlayerStatusesNode = gameSettingsNode->getChild("networkPlayerStatuses",idx);
networkPlayerStatuses[idx] = networkPlayerStatusesNode->getAttribute("status")->getIntValue();
}
// string networkPlayerLanguages[GameConstants::maxPlayers];
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
const XmlNode *networkPlayerLanguagesNode = gameSettingsNode->getChild("networkPlayerLanguages",idx);
networkPlayerLanguages[idx] = networkPlayerLanguagesNode->getAttribute("name")->getValue();
}
// ControlType factionControls[GameConstants::maxPlayers];
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
const XmlNode *factionControlsNode = gameSettingsNode->getChild("factionControls",idx);
factionControls[idx] = static_cast<ControlType>(factionControlsNode->getAttribute("control")->getIntValue());
}
// int resourceMultiplierIndex[GameConstants::maxPlayers];
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
const XmlNode *resourceMultiplierIndexNode = gameSettingsNode->getChild("resourceMultiplierIndex",idx);
resourceMultiplierIndex[idx] = resourceMultiplierIndexNode->getAttribute("multiplier")->getIntValue();
}
// int thisFactionIndex;
thisFactionIndex = gameSettingsNode->getAttribute("thisFactionIndex")->getIntValue();
// int factionCount;
factionCount = gameSettingsNode->getAttribute("factionCount")->getIntValue();
// int teams[GameConstants::maxPlayers];
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
const XmlNode *teamsNode = gameSettingsNode->getChild("teams",idx);
teams[idx] = teamsNode->getAttribute("team")->getIntValue();
}
// int startLocationIndex[GameConstants::maxPlayers];
for(int idx =0; idx < GameConstants::maxPlayers; idx++) {
const XmlNode *startLocationIndexNode = gameSettingsNode->getChild("startLocationIndex",idx);
startLocationIndex[idx] = startLocationIndexNode->getAttribute("location")->getIntValue();
}
// int mapFilterIndex;
mapFilterIndex = gameSettingsNode->getAttribute("mapFilterIndex")->getIntValue();
//
//
// bool defaultUnits;
defaultUnits = gameSettingsNode->getAttribute("defaultUnits")->getIntValue();
// bool defaultResources;
defaultResources = gameSettingsNode->getAttribute("defaultResources")->getIntValue();
// bool defaultVictoryConditions;
defaultVictoryConditions = gameSettingsNode->getAttribute("defaultVictoryConditions")->getIntValue();
// bool fogOfWar;
fogOfWar = gameSettingsNode->getAttribute("fogOfWar")->getIntValue();
// bool allowObservers;
allowObservers = gameSettingsNode->getAttribute("allowObservers")->getIntValue();
// bool enableObserverModeAtEndGame;
enableObserverModeAtEndGame = gameSettingsNode->getAttribute("enableObserverModeAtEndGame")->getIntValue();
// bool enableServerControlledAI;
enableServerControlledAI = gameSettingsNode->getAttribute("enableServerControlledAI")->getIntValue();
// int networkFramePeriod;
networkFramePeriod = gameSettingsNode->getAttribute("networkFramePeriod")->getIntValue();
// bool networkPauseGameForLaggedClients;
networkPauseGameForLaggedClients = gameSettingsNode->getAttribute("networkPauseGameForLaggedClients")->getIntValue();
// PathFinderType pathFinderType;
pathFinderType = static_cast<PathFinderType>(gameSettingsNode->getAttribute("pathFinderType")->getIntValue());
// uint32 flagTypes1;
flagTypes1 = gameSettingsNode->getAttribute("flagTypes1")->getIntValue();
// int32 mapCRC;
mapCRC = gameSettingsNode->getAttribute("mapCRC")->getIntValue();
// int32 tilesetCRC;
tilesetCRC = gameSettingsNode->getAttribute("tilesetCRC")->getIntValue();
// int32 techCRC;
techCRC = gameSettingsNode->getAttribute("techCRC")->getIntValue();
// vector<pair<string,int32> > factionCRCList;
// for(unsigned int i = 0; i < factionCRCList.size(); ++i) {
// const pair<string,int32> &item = factionCRCList[i];
//
// XmlNode *factionCRCListNode = gameSettingsNode->addChild("factionCRCList");
// factionCRCListNode->addAttribute("key",item.first, mapTagReplacements);
// factionCRCListNode->addAttribute("value",intToStr(item.second), mapTagReplacements);
// }
// int aiAcceptSwitchTeamPercentChance;
aiAcceptSwitchTeamPercentChance = gameSettingsNode->getAttribute("aiAcceptSwitchTeamPercentChance")->getIntValue();
// int masterserver_admin;
masterserver_admin = gameSettingsNode->getAttribute("masterserver_admin")->getIntValue();
}
};
}}//end namespace

View File

@ -3305,6 +3305,9 @@ int glestMain(int argc, char** argv) {
else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTOSTART_LASTGAME])) == true) {
program->initServer(mainWindow,true,false);
}
else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTOSTART_LAST_SAVED_GAME])) == true) {
program->initSavedGame(mainWindow,false);
}
else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_PREVIEW_MAP])) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_PREVIEW_MAP]) + string("="),&foundParamIndIndex);

View File

@ -200,6 +200,30 @@ void Program::initNormal(WindowGl *window){
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void Program::initSavedGame(WindowGl *window,bool masterserverMode) {
MainMenu* mainMenu= NULL;
init(window);
mainMenu= new MainMenu(this);
setState(mainMenu);
string saveGameFile = GameConstants::saveGameFileDefault;
if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
saveGameFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + saveGameFile;
}
else {
string userData = Config::getInstance().getString("UserData_Root","");
if(userData != "") {
endPathWithSlash(userData);
}
saveGameFile = userData + saveGameFile;
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Loading game from [%s]\n",saveGameFile.c_str());
Game::loadGame(saveGameFile,this,masterserverMode);
}
void Program::initServer(WindowGl *window, bool autostart,bool openNetworkSlots,
bool masterserverMode) {
MainMenu* mainMenu= NULL;

View File

@ -167,6 +167,7 @@ public:
void initNormal(WindowGl *window);
void initServer(WindowGl *window,bool autostart=false,bool openNetworkSlots=false,bool masterserverMode=false);
void initServer(WindowGl *window, GameSettings *settings);
void initSavedGame(WindowGl *window,bool masterserverMode=false);
void initClient(WindowGl *window, const Ip &serverIp);
void initScenario(WindowGl *window, string autoloadScenarioName);

View File

@ -382,6 +382,9 @@ Faction::Faction() {
startLocationIndex=0;
thisFaction=false;
currentSwitchTeamVoteFactionIndex = -1;
loadWorldNode = NULL;
techTree = NULL;
}
Faction::~Faction() {
@ -465,10 +468,13 @@ bool Faction::isWorkerThreadSignalCompleted(int frameIndex) {
void Faction::init(
FactionType *factionType, ControlType control, TechTree *techTree, Game *game,
int factionIndex, int teamIndex, int startLocationIndex, bool thisFaction, bool giveResources)
int factionIndex, int teamIndex, int startLocationIndex, bool thisFaction, bool giveResources,
const XmlNode *loadWorldNode)
{
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
this->techTree = techTree;
this->loadWorldNode = loadWorldNode;
this->control= control;
this->factionType= factionType;
this->startLocationIndex= startLocationIndex;
@ -481,11 +487,14 @@ void Faction::init(
resources.resize(techTree->getResourceTypeCount());
store.resize(techTree->getResourceTypeCount());
for(int i=0; i<techTree->getResourceTypeCount(); ++i){
const ResourceType *rt= techTree->getResourceType(i);
int resourceAmount= giveResources? factionType->getStartingResourceAmount(rt): 0;
resources[i].init(rt, resourceAmount);
store[i].init(rt, 0);
if(loadWorldNode == NULL) {
for(int i=0; i<techTree->getResourceTypeCount(); ++i){
const ResourceType *rt= techTree->getResourceType(i);
int resourceAmount= giveResources? factionType->getStartingResourceAmount(rt): 0;
resources[i].init(rt, resourceAmount);
store[i].init(rt, 0);
}
}
texture= Renderer::getInstance().newTexture2D(rsGame);
@ -495,6 +504,10 @@ void Faction::init(
texture->load(playerTexture);
}
if(loadWorldNode != NULL) {
loadGame(loadWorldNode, factionIndex,game->getGameSettings(),game->getWorld());
}
if( game->getGameSettings()->getPathFinderType() == pfBasic &&
Config::getInstance().getBool("EnableFactionWorkerThreads","true") == true) {
if(workerThread != NULL) {
@ -520,6 +533,11 @@ const Resource *Faction::getResource(const ResourceType *rt) const{
return &resources[i];
}
}
printf("ERROR cannot find resource type [%s] in list:\n",(rt != NULL ? rt->getName().c_str() : "null"));
for(int i=0; i<resources.size(); ++i){
printf("Index %d [%s]",i,resources[i].getType()->getName().c_str());
}
assert(false);
return NULL;
}
@ -530,6 +548,11 @@ int Faction::getStoreAmount(const ResourceType *rt) const{
return store[i].getAmount();
}
}
printf("ERROR cannot find store type [%s] in list:\n",(rt != NULL ? rt->getName().c_str() : "null"));
for(int i=0; i<store.size(); ++i){
printf("Index %d [%s]",i,store[i].getType()->getName().c_str());
}
assert(false);
return 0;
}
@ -1773,6 +1796,12 @@ void Faction::saveGame(XmlNode *rootNode) {
resource.saveGame(factionNode);
}
// Store store;
XmlNode *storeNode = factionNode->addChild("Store");
for(unsigned int i = 0; i < store.size(); ++i) {
Resource &resource = store[i];
resource.saveGame(storeNode);
}
// Allies allies;
for(unsigned int i = 0; i < allies.size(); ++i) {
Faction *ally = allies[i];
@ -1834,4 +1863,47 @@ void Faction::saveGame(XmlNode *rootNode) {
}
void Faction::loadGame(const XmlNode *rootNode, int index,GameSettings *settings,World *world) {
XmlNode *factionNode = NULL;
vector<XmlNode *> factionNodeList = rootNode->getChildList("Faction");
for(unsigned int i = 0; i < factionNodeList.size(); ++i) {
XmlNode *node = factionNodeList[i];
if(node->getAttribute("index")->getIntValue() == index) {
factionNode = node;
break;
}
}
if(factionNode != NULL) {
vector<XmlNode *> unitNodeList = factionNode->getChildList("Unit");
for(unsigned int i = 0; i < unitNodeList.size(); ++i) {
XmlNode *unitNode = unitNodeList[i];
Unit *unit = Unit::loadGame(unitNode,settings,this, world);
this->addUnit(unit);
}
//description = gameSettingsNode->getAttribute("description")->getValue();
}
//resources.resize(techTree->getResourceTypeCount());
//store.resize(techTree->getResourceTypeCount());
// for(int i=0; i<techTree->getResourceTypeCount(); ++i){
// const ResourceType *rt= techTree->getResourceType(i);
// int resourceAmount= giveResources? factionType->getStartingResourceAmount(rt): 0;
// resources[i].init(rt, resourceAmount);
// store[i].init(rt, 0);
// }
for(unsigned int i = 0; i < resources.size(); ++i) {
Resource &resource = resources[i];
resource.loadGame(factionNode,i,techTree);
}
XmlNode *storeNode = factionNode->getChild("Store");
for(unsigned int i = 0; i < store.size(); ++i) {
Resource &resource = store[i];
resource.loadGame(storeNode,i,techTree);
}
}
}}//end namespace

View File

@ -44,6 +44,7 @@ class Game;
class ScriptManager;
class World;
class Faction;
class GameSettings;
// =====================================================
// class Faction
@ -138,6 +139,9 @@ private:
set<int> livingUnits;
set<Unit*> livingUnitsp;
TechTree *techTree;
const XmlNode *loadWorldNode;
public:
Faction();
~Faction();
@ -151,7 +155,8 @@ public:
void init(
FactionType *factionType, ControlType control, TechTree *techTree, Game *game,
int factionIndex, int teamIndex, int startLocationIndex, bool thisFaction, bool giveResources);
int factionIndex, int teamIndex, int startLocationIndex, bool thisFaction,
bool giveResources, const XmlNode *loadWorldNode=NULL);
void end();
bool getFactionDisconnectHandled() const { return factionDisconnectHandled;}
@ -257,6 +262,7 @@ public:
std::string toString() const;
void saveGame(XmlNode *rootNode);
void loadGame(const XmlNode *rootNode, int index,GameSettings *settings,World *world);
private:
void resetResourceAmount(const ResourceType *rt);

View File

@ -181,4 +181,36 @@ string Object::getUniquePickName() const {
return result;
}
void Object::saveGame(XmlNode *rootNode) {
std::map<string,string> mapTagReplacements;
XmlNode *objectNode = rootNode->addChild("Object");
// ObjectType *objectType;
if(objectType != NULL) {
objectNode->addAttribute("objectType",intToStr(objectType->getClass()), mapTagReplacements);
}
// vector<UnitParticleSystem*> unitParticleSystems;
for(unsigned int i = 0; i < unitParticleSystems.size(); ++i) {
UnitParticleSystem *ptr= unitParticleSystems[i];
if(ptr != NULL) {
ptr->saveGame(objectNode);
}
}
// Resource *resource;
if(resource != NULL) {
resource->saveGame(objectNode);
}
// Vec3f pos;
objectNode->addAttribute("pos",pos.getString(), mapTagReplacements);
// float rotation;
objectNode->addAttribute("rotation",floatToStr(rotation), mapTagReplacements);
// int variation;
objectNode->addAttribute("variation",intToStr(variation), mapTagReplacements);
// int lastRenderFrame;
objectNode->addAttribute("lastRenderFrame",intToStr(lastRenderFrame), mapTagReplacements);
// Vec2i mapPos;
objectNode->addAttribute("mapPos",mapPos.getString(), mapTagReplacements);
// bool visible;
objectNode->addAttribute("visible",intToStr(visible), mapTagReplacements);
}
}}//end namespace

View File

@ -88,6 +88,7 @@ public:
const Vec2i & getMapPos() const { return mapPos; }
virtual string getUniquePickName() const;
void saveGame(XmlNode *rootNode);
};
}}//end namespace

View File

@ -16,6 +16,7 @@
#include "checksum.h"
#include <stdexcept>
#include "util.h"
#include "tech_tree.h"
#include "leak_dumper.h"
using namespace Shared::Graphics;
@ -115,4 +116,17 @@ void Resource::saveGame(XmlNode *rootNode) const {
resourceNode->addAttribute("balance",intToStr(balance), mapTagReplacements);
}
void Resource::loadGame(const XmlNode *rootNode, int index,TechTree *techTree) {
vector<XmlNode *> resourceNodeList = rootNode->getChildList("Resource");
if(index < resourceNodeList.size()) {
XmlNode *resourceNode = resourceNodeList[index];
amount = resourceNode->getAttribute("amount")->getIntValue();
type = techTree->getResourceType(resourceNode->getAttribute("type")->getValue());
pos = Vec2i::strToVec2(resourceNode->getAttribute("pos")->getValue());
balance = resourceNode->getAttribute("balance")->getIntValue();
}
}
}}//end namespace

View File

@ -27,7 +27,7 @@ using Shared::Graphics::Vec2i;
using Shared::PlatformCommon::ValueCheckerVault;
class ResourceType;
class TechTree;
// =====================================================
// class Resource
//
@ -59,6 +59,7 @@ public:
bool decAmount(int i);
void saveGame(XmlNode *rootNode) const;
void loadGame(const XmlNode *rootNode, int index,TechTree *techTree);
};
}}// end namespace

View File

@ -3530,9 +3530,9 @@ void Unit::saveGame(XmlNode *rootNode) {
(*it)->saveGame(unitNode);
}
// Observers observers;
for(Observers::iterator it = observers.begin(); it != observers.end(); ++it) {
(*it)->saveGame(unitNode);
}
//for(Observers::iterator it = observers.begin(); it != observers.end(); ++it) {
// (*it)->saveGame(unitNode);
//}
// vector<UnitParticleSystem*> unitParticleSystems;
for(unsigned int i = 0; i < unitParticleSystems.size(); ++i) {
@ -3651,4 +3651,44 @@ void Unit::saveGame(XmlNode *rootNode) {
unitNode->addAttribute("causeOfDeath",intToStr(causeOfDeath), mapTagReplacements);
}
Unit * Unit::loadGame(const XmlNode *rootNode, GameSettings *settings, Faction *faction, World *world) {
const XmlNode *unitNode = rootNode;
int newUnitId = unitNode->getAttribute("id")->getIntValue();
Vec2i newUnitPos = Vec2i::strToVec2(unitNode->getAttribute("pos")->getValue());
string newUnitType = unitNode->getAttribute("type")->getValue();
const UnitType *ut = faction->getType()->getUnitType(newUnitType);
CardinalDir newModelFacing = static_cast<CardinalDir>(unitNode->getAttribute("modelFacing")->getIntValue());
// Unit *result = new Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos,
// const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing) : BaseColorPickEntity(), id(id) {
UnitPathInterface *newpath = NULL;
switch(settings->getPathFinderType()) {
case pfBasic:
newpath = new UnitPathBasic();
break;
case pfRoutePlanner:
newpath = new UnitPath();
break;
default:
throw runtime_error("detected unsupported pathfinder type!");
}
//Unit *result = new Unit(getNextUnitId(f), newpath, Vec2i(0), ut, f, &map, CardinalDir::NORTH);
//Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing);
Unit *result = new Unit(newUnitId, newpath, newUnitPos, ut, faction, world->getMapPtr(), newModelFacing);
result->lastRotation = unitNode->getAttribute("lastRotation")->getFloatValue();
result->targetRotation = unitNode->getAttribute("targetRotation")->getFloatValue();
result->rotation = unitNode->getAttribute("rotation")->getFloatValue();
//world->placeUnitAtLocation(newUnitPos, generationArea, unit, true);
result->setPos(newUnitPos);
Vec2i meetingPos = newUnitPos-Vec2i(1);
result->setMeetingPos(meetingPos);
return result;
}
}}//end namespace

View File

@ -49,6 +49,8 @@ class Level;
class MorphCommandType;
class Game;
class Unit;
class GameSettings;
class World;
enum CommandResult {
crSuccess,
@ -641,6 +643,7 @@ public:
virtual string getUniquePickName() const;
void saveGame(XmlNode *rootNode);
static Unit * loadGame(const XmlNode *rootNode,GameSettings *settings,Faction *faction, World *world);
private:
float computeHeight(const Vec2i &pos) const;

View File

@ -378,37 +378,37 @@ void TechTree::saveGame(XmlNode *rootNode) {
techTreeNode->addAttribute("name",name, mapTagReplacements);
// //string desc;
// string treePath;
techTreeNode->addAttribute("treePath",treePath, mapTagReplacements);
//techTreeNode->addAttribute("treePath",treePath, mapTagReplacements);
// vector<string> pathList;
for(unsigned int i = 0; i < pathList.size(); ++i) {
XmlNode *pathListNode = techTreeNode->addChild("pathList");
pathListNode->addAttribute("value",pathList[i], mapTagReplacements);
}
// for(unsigned int i = 0; i < pathList.size(); ++i) {
// XmlNode *pathListNode = techTreeNode->addChild("pathList");
// pathListNode->addAttribute("value",pathList[i], mapTagReplacements);
// }
// ResourceTypes resourceTypes;
for(unsigned int i = 0; i < resourceTypes.size(); ++i) {
ResourceType &rt = resourceTypes[i];
rt.saveGame(techTreeNode);
}
// for(unsigned int i = 0; i < resourceTypes.size(); ++i) {
// ResourceType &rt = resourceTypes[i];
// rt.saveGame(techTreeNode);
// }
// FactionTypes factionTypes;
for(unsigned int i = 0; i < factionTypes.size(); ++i) {
FactionType &ft = factionTypes[i];
ft.saveGame(techTreeNode);
}
// for(unsigned int i = 0; i < factionTypes.size(); ++i) {
// FactionType &ft = factionTypes[i];
// ft.saveGame(techTreeNode);
// }
// ArmorTypes armorTypes;
for(unsigned int i = 0; i < armorTypes.size(); ++i) {
ArmorType &at = armorTypes[i];
at.saveGame(techTreeNode);
}
// for(unsigned int i = 0; i < armorTypes.size(); ++i) {
// ArmorType &at = armorTypes[i];
// at.saveGame(techTreeNode);
// }
// AttackTypes attackTypes;
for(unsigned int i = 0; i < attackTypes.size(); ++i) {
AttackType &at = attackTypes[i];
at.saveGame(techTreeNode);
}
// for(unsigned int i = 0; i < attackTypes.size(); ++i) {
// AttackType &at = attackTypes[i];
// at.saveGame(techTreeNode);
// }
// DamageMultiplierTable damageMultiplierTable;
damageMultiplierTable.saveGame(techTreeNode);
// damageMultiplierTable.saveGame(techTreeNode);
// Checksum checksumValue;
techTreeNode->addAttribute("checksumValue",intToStr(checksumValue.getSum()), mapTagReplacements);

View File

@ -26,8 +26,10 @@
#include "pos_iterator.h"
#include "faction.h"
#include "command.h"
#include "leak_dumper.h"
#include "map_preview.h"
#include "world.h"
#include "leak_dumper.h"
using namespace Shared::Graphics;
using namespace Shared::Util;
@ -76,6 +78,70 @@ bool Cell::isFreeOrMightBeFreeSoon(Vec2i originPos, Vec2i cellPos, Field field)
return result;
}
void Cell::saveGame(XmlNode *rootNode, int index) const {
bool saveCell = false;
if(saveCell == false) {
for(unsigned int i = 0; i < fieldCount; ++i) {
if(units[i] != NULL) {
saveCell = true;
break;
}
if(unitsWithEmptyCellMap[i] != NULL) {
saveCell = true;
break;
}
}
}
if(saveCell == true) {
std::map<string,string> mapTagReplacements;
XmlNode *cellNode = rootNode->addChild("Cell" + intToStr(index));
cellNode->addAttribute("index",intToStr(index), mapTagReplacements);
// Unit *units[fieldCount]; //units on this cell
for(unsigned int i = 0; i < fieldCount; ++i) {
if(units[i] != NULL) {
XmlNode *unitsNode = cellNode->addChild("units");
unitsNode->addAttribute("field",intToStr(i), mapTagReplacements);
unitsNode->addAttribute("unitid",intToStr(units[i]->getId()), mapTagReplacements);
}
}
// Unit *unitsWithEmptyCellMap[fieldCount]; //units with an empty cellmap on this cell
for(unsigned int i = 0; i < fieldCount; ++i) {
if(unitsWithEmptyCellMap[i] != NULL) {
XmlNode *unitsWithEmptyCellMapNode = cellNode->addChild("unitsWithEmptyCellMap");
unitsWithEmptyCellMapNode->addAttribute("field",intToStr(i), mapTagReplacements);
unitsWithEmptyCellMapNode->addAttribute("unitid",intToStr(unitsWithEmptyCellMap[i]->getId()), mapTagReplacements);
}
}
// float height;
cellNode->addAttribute("height",floatToStr(height), mapTagReplacements);
}
}
void Cell::loadGame(const XmlNode *rootNode, int index, World *world) {
if(rootNode->hasChild("Cell" + intToStr(index)) == true) {
const XmlNode *cellNode = rootNode->getChild("Cell" + intToStr(index));
int unitCount = cellNode->getChildCount();
for(unsigned int i = 0; i < unitCount; ++i) {
if(cellNode->hasChildAtIndex("units",i) == true) {
const XmlNode *unitsNode = cellNode->getChild("units",i);
int field = unitsNode->getAttribute("field")->getIntValue();
int unitId = unitsNode->getAttribute("unitid")->getIntValue();
units[field] = world->findUnitById(unitId);
}
if(cellNode->hasChildAtIndex("unitsWithEmptyCellMap",i) == true) {
const XmlNode *unitsNode = cellNode->getChild("unitsWithEmptyCellMap",i);
int field = unitsNode->getAttribute("field")->getIntValue();
int unitId = unitsNode->getAttribute("unitid")->getIntValue();
unitsWithEmptyCellMap[field] = world->findUnitById(unitId);
}
}
}
}
// =====================================================
// class SurfaceCell
// =====================================================
@ -127,6 +193,95 @@ void SurfaceCell::setVisible(int teamIndex, bool visible) {
this->visible[teamIndex]= visible;
}
void SurfaceCell::saveGame(XmlNode *rootNode,int index) const {
bool saveCell = (object != NULL);
if(saveCell == false) {
for(unsigned int i = 0; i < GameConstants::maxPlayers; ++i) {
if(visible[i] == true || explored[i] == true) {
saveCell = true;
}
}
}
if(saveCell == true) {
std::map<string,string> mapTagReplacements;
XmlNode *surfaceCellNode = rootNode->addChild("SurfaceCell" + intToStr(index));
surfaceCellNode->addAttribute("index",intToStr(index), mapTagReplacements);
// //geometry
// Vec3f vertex;
//surfaceCellNode->addAttribute("vertex",vertex.getString(), mapTagReplacements);
// Vec3f normal;
//surfaceCellNode->addAttribute("normal",normal.getString(), mapTagReplacements);
// Vec3f color;
//surfaceCellNode->addAttribute("color",color.getString(), mapTagReplacements);
//
// //tex coords
// Vec2f fowTexCoord; //tex coords for TEXTURE1 when multitexturing and fogOfWar
//surfaceCellNode->addAttribute("fowTexCoord",fowTexCoord.getString(), mapTagReplacements);
// Vec2f surfTexCoord; //tex coords for TEXTURE0
//surfaceCellNode->addAttribute("surfTexCoord",surfTexCoord.getString(), mapTagReplacements);
// //surface
// int surfaceType;
//surfaceCellNode->addAttribute("surfaceType",intToStr(surfaceType), mapTagReplacements);
// const Texture2D *surfaceTexture;
//
// //object & resource
// Object *object;
if(object != NULL) {
object->saveGame(surfaceCellNode);
}
// //visibility
// bool visible[GameConstants::maxPlayers + GameConstants::specialFactions];
for(unsigned int i = 0; i < GameConstants::maxPlayers; ++i) {
if(visible[i] == true) {
XmlNode *visibleNode = surfaceCellNode->addChild("visible");
visibleNode->addAttribute("index",intToStr(i), mapTagReplacements);
visibleNode->addAttribute("value",intToStr(visible[i]), mapTagReplacements);
}
}
// bool explored[GameConstants::maxPlayers + GameConstants::specialFactions];
for(unsigned int i = 0; i < GameConstants::maxPlayers; ++i) {
if(explored[i] == true) {
XmlNode *exploredNode = surfaceCellNode->addChild("explored");
exploredNode->addAttribute("index",intToStr(i), mapTagReplacements);
exploredNode->addAttribute("value",intToStr(explored[i]), mapTagReplacements);
}
}
// //cache
// bool nearSubmerged;
//surfaceCellNode->addAttribute("nearSubmerged",intToStr(nearSubmerged), mapTagReplacements);
}
}
void SurfaceCell::loadGame(const XmlNode *rootNode, int index, World *world) {
if(rootNode->hasChild("SurfaceCell" + intToStr(index)) == true) {
const XmlNode *cellNode = rootNode->getChild("SurfaceCell" + intToStr(index));
int visibleCount = cellNode->getChildCount();
//printf("Loading game, sc index [%d][%d]\n",index,visibleCount);
for(unsigned int i = 0; i < visibleCount; ++i) {
if(cellNode->hasChildAtIndex("visible",i) == true) {
const XmlNode *visibleNode = cellNode->getChild("visible",i);
int indexCell = visibleNode->getAttribute("index")->getIntValue();
bool value = visibleNode->getAttribute("value")->getIntValue();
visible[indexCell] = value;
//printf("Loading game, sc visible index [%d][%d][%d]\n",index,indexCell,value);
}
if(cellNode->hasChildAtIndex("explored",i) == true) {
const XmlNode *exploredNode = cellNode->getChild("explored",i);
int indexCell = exploredNode->getAttribute("index")->getIntValue();
bool value = exploredNode->getAttribute("value")->getIntValue();
explored[indexCell] = value;
//printf("Loading game, sc explored index [%d][%d][%d]\n",index,indexCell,value);
}
}
}
}
// =====================================================
// class Map
// =====================================================
@ -1649,6 +1804,84 @@ string Map::getMapPath(const string &mapName, string scenarioDir, bool errorOnNo
return "";
}
void Map::saveGame(XmlNode *rootNode) const {
std::map<string,string> mapTagReplacements;
XmlNode *mapNode = rootNode->addChild("Map");
// string title;
mapNode->addAttribute("title",title, mapTagReplacements);
// float waterLevel;
mapNode->addAttribute("waterLevel",floatToStr(waterLevel), mapTagReplacements);
// float heightFactor;
mapNode->addAttribute("heightFactor",floatToStr(heightFactor), mapTagReplacements);
// float cliffLevel;
mapNode->addAttribute("cliffLevel",floatToStr(cliffLevel), mapTagReplacements);
// int cameraHeight;
mapNode->addAttribute("cameraHeight",intToStr(cameraHeight), mapTagReplacements);
// int w;
mapNode->addAttribute("w",intToStr(w), mapTagReplacements);
// int h;
mapNode->addAttribute("h",intToStr(h), mapTagReplacements);
// int surfaceW;
mapNode->addAttribute("surfaceW",intToStr(surfaceW), mapTagReplacements);
// int surfaceH;
mapNode->addAttribute("surfaceH",intToStr(surfaceH), mapTagReplacements);
// int maxPlayers;
mapNode->addAttribute("maxPlayers",intToStr(maxPlayers), mapTagReplacements);
// Cell *cells;
//printf("getCellArraySize() = %d\n",getCellArraySize());
for(unsigned int i = 0; i < getCellArraySize(); ++i) {
Cell &cell = cells[i];
cell.saveGame(mapNode,i);
}
// SurfaceCell *surfaceCells;
//printf("getSurfaceCellArraySize() = %d\n",getSurfaceCellArraySize());
for(unsigned int i = 0; i < getSurfaceCellArraySize(); ++i) {
SurfaceCell &surfaceCell = surfaceCells[i];
surfaceCell.saveGame(mapNode,i);
}
// Vec2i *startLocations;
for(unsigned int i = 0; i < maxPlayers; ++i) {
XmlNode *startLocationsNode = mapNode->addChild("startLocations");
startLocationsNode->addAttribute("location",startLocations[i].getString(), mapTagReplacements);
}
// Checksum checksumValue;
// mapNode->addAttribute("checksumValue",intToStr(checksumValue.getSum()), mapTagReplacements);
// float maxMapHeight;
mapNode->addAttribute("maxMapHeight",floatToStr(maxMapHeight), mapTagReplacements);
// string mapFile;
mapNode->addAttribute("mapFile",mapFile, mapTagReplacements);
}
void Map::loadGame(const XmlNode *rootNode, World *world) {
const XmlNode *mapNode = rootNode->getChild("World")->getChild("Map");
//description = gameSettingsNode->getAttribute("description")->getValue();
// for(unsigned int i = 0; i < getCellArraySize(); ++i) {
// Cell &cell = cells[i];
// cell.saveGame(mapNode,i);
// }
// for(unsigned int i = 0; i < getSurfaceCellArraySize(); ++i) {
// SurfaceCell &surfaceCell = surfaceCells[i];
// surfaceCell.saveGame(mapNode,i);
// }
printf("getCellArraySize() = %d\n",getCellArraySize());
for(unsigned int i = 0; i < getCellArraySize(); ++i) {
Cell &cell = cells[i];
cell.loadGame(mapNode,i,world);
}
printf("getSurfaceCellArraySize() = %d\n",getSurfaceCellArraySize());
for(unsigned int i = 0; i < getSurfaceCellArraySize(); ++i) {
SurfaceCell &surfaceCell = surfaceCells[i];
surfaceCell.loadGame(mapNode,i,world);
}
}
// =====================================================
// class PosCircularIterator
// =====================================================

View File

@ -38,7 +38,7 @@ class Unit;
class Resource;
class TechTree;
class GameSettings;
class World;
// =====================================================
// class Cell
//
@ -70,6 +70,9 @@ public:
bool isFree(Field field) const;
bool isFreeOrMightBeFreeSoon(Vec2i originPos, Vec2i cellPos, Field field) const;
void saveGame(XmlNode *rootNode,int index) const;
void loadGame(const XmlNode *rootNode, int index, World *world);
};
// =====================================================
@ -141,6 +144,9 @@ public:
//misc
void deleteResource();
bool isFree() const;
void saveGame(XmlNode *rootNode,int index) const;
void loadGame(const XmlNode *rootNode, int index, World *world);
};
@ -266,6 +272,9 @@ public:
string getMapFile() const { return mapFile; }
void saveGame(XmlNode *rootNode) const;
void loadGame(const XmlNode *rootNode,World *world);
private:
//compute
void smoothSurface(Tileset *tileset);

View File

@ -134,11 +134,20 @@ void TimeFlow::saveGame(XmlNode *rootNode) {
// bool firstTime;
// Tileset *tileset;
// float time;
timeflowNode->addAttribute("time",intToStr(time), mapTagReplacements);
timeflowNode->addAttribute("time",floatToStr(time), mapTagReplacements);
// float lastTime;
timeflowNode->addAttribute("lastTime",intToStr(lastTime), mapTagReplacements);
timeflowNode->addAttribute("lastTime",floatToStr(lastTime), mapTagReplacements);
// float timeInc;
timeflowNode->addAttribute("timeInc",intToStr(timeInc), mapTagReplacements);
timeflowNode->addAttribute("timeInc",floatToStr(timeInc), mapTagReplacements);
}
void TimeFlow::loadGame(const XmlNode *rootNode) {
const XmlNode *timeflowNode = rootNode->getChild("TimeFlow");
firstTime = timeflowNode->getAttribute("firstTime")->getFloatValue();
time = timeflowNode->getAttribute("time")->getIntValue();
lastTime = timeflowNode->getAttribute("lastTime")->getFloatValue();
timeInc = timeflowNode->getAttribute("timeInc")->getFloatValue();
}
}}//end namespace

View File

@ -61,6 +61,7 @@ public:
void update();
void saveGame(XmlNode *rootNode);
void loadGame(const XmlNode *rootNode);
private:
//bool isAproxTime(float time) const;

View File

@ -82,6 +82,8 @@ World::World(){
queuedScenarioName="";
queuedScenarioKeepFactions=false;
loadWorldNode = NULL;
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
@ -228,6 +230,10 @@ void World::init(Game *game, bool createUnits, bool initFactions){
fogOfWar = gs->getFogOfWar();
}
if(loadWorldNode != NULL) {
timeFlow.loadGame(loadWorldNode);
}
if(initFactions == true) {
initFactionTypes(gs);
}
@ -1311,7 +1317,8 @@ void World::initFactionTypes(GameSettings *gs) {
throw runtime_error("ft == NULL");
}
factions[i]->init(ft, gs->getFactionControl(i), techTree, game, i, gs->getTeam(i),
gs->getStartLocationIndex(i), i==thisFactionIndex, gs->getDefaultResources());
gs->getStartLocationIndex(i), i==thisFactionIndex,
gs->getDefaultResources(),loadWorldNode);
stats.setTeam(i, gs->getTeam(i));
stats.setFactionTypeName(i, formatString(gs->getFactionTypeName(i)));
@ -1385,60 +1392,87 @@ void World::initUnitsForScenario() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void World::placeUnitAtLocation(const Vec2i &location, int radius, Unit *unit, bool spaciated) {
if(placeUnit(location, generationArea, unit, spaciated)) {
unit->create(true);
unit->born();
}
else {
string unitName = unit->getType()->getName();
delete unit;
unit = NULL;
char szBuf[4096]="";
sprintf(szBuf,"Unit: [%s] can't be placed, this error is caused because there\nis not enough room to put all units near their start location.\nmake a better/larger map. Faction: #%d name: [%s]",
unitName.c_str(),unit->getFactionIndex(),unit->getFaction()->getType()->getName().c_str());
throw runtime_error(szBuf);
}
if (unit->getType()->hasSkillClass(scBeBuilt)) {
map.flatternTerrain(unit);
if(cartographer != NULL) {
cartographer->updateMapMetrics(unit->getPos(), unit->getType()->getSize());
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str());
}
//place units randomly aroud start location
void World::initUnits() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
Logger::getInstance().add(Lang::getInstance().get("LogScreenGameLoadingGenerateGameElements","",true), true);
//put starting units
for(int i = 0; i < getFactionCount(); ++i) {
Faction *f= factions[i];
const FactionType *ft= f->getType();
if(loadWorldNode == NULL) {
for(int i = 0; i < getFactionCount(); ++i) {
Faction *f= factions[i];
const FactionType *ft= f->getType();
for(int j = 0; j < ft->getStartingUnitCount(); ++j) {
const UnitType *ut= ft->getStartingUnit(j);
int initNumber= ft->getStartingUnitAmount(j);
for(int j = 0; j < ft->getStartingUnitCount(); ++j) {
const UnitType *ut= ft->getStartingUnit(j);
int initNumber= ft->getStartingUnitAmount(j);
for(int l = 0; l < initNumber; l++) {
for(int l = 0; l < initNumber; l++) {
UnitPathInterface *newpath = NULL;
switch(game->getGameSettings()->getPathFinderType()) {
case pfBasic:
newpath = new UnitPathBasic();
break;
case pfRoutePlanner:
newpath = new UnitPath();
break;
default:
throw runtime_error("detected unsupported pathfinder type!");
}
Unit *unit= new Unit(getNextUnitId(f), newpath, Vec2i(0), ut, f, &map, CardinalDir::NORTH);
int startLocationIndex= f->getStartLocationIndex();
if(placeUnit(map.getStartLocation(startLocationIndex), generationArea, unit, true)) {
unit->create(true);
unit->born();
}
else {
string unitName = unit->getType()->getName();
delete unit;
unit = NULL;
throw runtime_error("Unit: " + unitName + " can't be placed, this error is caused because there\nis not enough room to put all units near their start location.\nmake a better/larger map. Faction: #" + intToStr(i) + " name: " + ft->getName());
}
if (unit->getType()->hasSkillClass(scBeBuilt)) {
map.flatternTerrain(unit);
if(cartographer != NULL) {
cartographer->updateMapMetrics(unit->getPos(), unit->getType()->getSize());
UnitPathInterface *newpath = NULL;
switch(game->getGameSettings()->getPathFinderType()) {
case pfBasic:
newpath = new UnitPathBasic();
break;
case pfRoutePlanner:
newpath = new UnitPath();
break;
default:
throw runtime_error("detected unsupported pathfinder type!");
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str());
}
}
// Ensure Starting Resource Amount are adjusted to max store levels
f->limitResourcesToStore();
Unit *unit= new Unit(getNextUnitId(f), newpath, Vec2i(0), ut, f, &map, CardinalDir::NORTH);
int startLocationIndex= f->getStartLocationIndex();
// if(placeUnit(map.getStartLocation(startLocationIndex), generationArea, unit, true)) {
// unit->create(true);
// unit->born();
// }
// else {
// string unitName = unit->getType()->getName();
// delete unit;
// unit = NULL;
// throw runtime_error("Unit: " + unitName + " can't be placed, this error is caused because there\nis not enough room to put all units near their start location.\nmake a better/larger map. Faction: #" + intToStr(i) + " name: " + ft->getName());
// }
// if (unit->getType()->hasSkillClass(scBeBuilt)) {
// map.flatternTerrain(unit);
// if(cartographer != NULL) {
// cartographer->updateMapMetrics(unit->getPos(), unit->getType()->getSize());
// }
// }
placeUnitAtLocation(map.getStartLocation(startLocationIndex), generationArea, unit, true);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str());
}
}
// Ensure Starting Resource Amount are adjusted to max store levels
f->limitResourcesToStore();
}
}
map.computeNormals();
map.computeInterpolatedHeights();
@ -1999,7 +2033,7 @@ void World::saveGame(XmlNode *rootNode) {
XmlNode *worldNode = rootNode->addChild("World");
// Map map;
worldNode->addAttribute("map",extractFileFromDirectoryPath(map.getMapFile()), mapTagReplacements);
//map.saveGame(worldNode);
// Tileset tileset;
worldNode->addAttribute("tileset",tileset.getName(), mapTagReplacements);
// //TechTree techTree;
@ -2074,4 +2108,8 @@ void World::saveGame(XmlNode *rootNode) {
worldNode->addAttribute("queuedScenarioKeepFactions",intToStr(queuedScenarioKeepFactions), mapTagReplacements);
}
void World::loadGame(const XmlNode *rootNode) {
loadWorldNode = rootNode;
}
}}//end namespace

View File

@ -146,6 +146,8 @@ private:
string queuedScenarioName;
bool queuedScenarioKeepFactions;
const XmlNode *loadWorldNode;
public:
World();
~World();
@ -267,7 +269,9 @@ public:
string getFowAlphaCellsLookupItemCacheStats();
string getAllFactionsCacheStats();
void placeUnitAtLocation(const Vec2i &location, int radius, Unit *unit, bool spaciated);
void saveGame(XmlNode *rootNode);
void loadGame(const XmlNode *rootNode);
private:

View File

@ -16,10 +16,48 @@
#include "math_wrapper.h"
#include <string>
#include <sstream>
#include <vector>
#include <stdexcept>
#include <stdlib.h>
#include <stdio.h>
#include "leak_dumper.h"
namespace Shared{ namespace Graphics{
inline std::vector<std::string> TokenizeString(const std::string str,const std::string delimiters) {
std::vector<std::string> tokens;
// Assume textLine contains the line of text to parse.
std::string textLine = str;
std::size_t pos = 0;
while( true ) {
std::size_t nextPos = textLine.find( delimiters, pos );
if( nextPos == textLine.npos ) {
tokens.push_back(textLine.substr(pos, textLine.length( )));
break;
}
tokens.push_back( std::string( textLine.substr( pos, nextPos - pos ) ) );
pos = nextPos + 1;
}
return tokens;
}
template<typename T>
inline T strToType(const std::string &s) {
char *endChar=NULL;
setlocale(LC_NUMERIC, "C");
T value= static_cast<T>(strtod(s.c_str(), &endChar));
if(*endChar!='\0'){
throw std::runtime_error("Error converting from string to type, found: [" + s + "]");
}
return value;
}
template<typename T> class Vec2;
template<typename T> class Vec3;
template<typename T> class Vec4;
@ -179,6 +217,35 @@ public:
streamOut << "] y [" << y << "]";
std::string result = streamOut.str();
streamOut.str(std::string());
return result;
}
// meetingPos="x [32] y [120]"
static inline Vec2<T> strToVec2(std::string value) {
Vec2<T> result;
std::vector<std::string> tokens = TokenizeString(value,"[");
//for(unsigned int i = 0; i < tokens.size(); ++i) {
//printf("#1 Vec2T i = %d [%s]\n",i,tokens[i].c_str());
//}
if(tokens.size() == 3) {
std::vector<std::string> tokens2 = TokenizeString(tokens[1],"]");
//for(unsigned int i = 0; i < tokens2.size(); ++i) {
//printf("#2 Vec2T i = %d [%s]\n",i,tokens2[i].c_str());
//}
std::vector<std::string> tokens3 = TokenizeString(tokens[2],"]");
//for(unsigned int i = 0; i < tokens3.size(); ++i) {
//printf("#3 Vec2T i = %d [%s]\n",i,tokens3[i].c_str());
//}
if(tokens2.size() == 2 && tokens3.size() == 2) {
result.x = (T)strToType<T>(tokens2[0]);
result.y = (T)strToType<T>(tokens3[0]);
//printf("#3 Vec2T [%s]\n",result.getString().c_str());
}
}
return result;
}
};

View File

@ -26,6 +26,7 @@ const char *GAME_ARGS[] = {
"--help",
"--autostart-lastgame",
"--load-saved-game",
"--connecthost",
"--starthost",
"--headless-server-mode",
@ -76,6 +77,7 @@ enum GAME_ARG_TYPE {
GAME_ARG_HELP = 0,
GAME_ARG_AUTOSTART_LASTGAME,
GAME_ARG_AUTOSTART_LAST_SAVED_GAME,
GAME_ARG_CLIENT,
GAME_ARG_SERVER,
GAME_ARG_MASTERSERVER_MODE,
@ -135,8 +137,12 @@ void printParameterHelp(const char *argv0, bool foundInvalidArgs) {
printf("Commandline Parameter:\t\tDescription:");
printf("\n----------------------\t\t------------");
printf("\n%s\t\t\t\tdisplays this help text.",GAME_ARGS[GAME_ARG_HELP]);
printf("\n%s\t\tAutomatically starts a game with the last game",GAME_ARGS[GAME_ARG_AUTOSTART_LASTGAME]);
printf("\n\t\t\t\tsettings you played.");
printf("\n%s\t\tLoads the last saved game.",GAME_ARGS[GAME_ARG_AUTOSTART_LAST_SAVED_GAME]);
printf("\n%s=x\t\t\tAuto connect to host server at IP or hostname x",GAME_ARGS[GAME_ARG_CLIENT]);
printf("\n%s\t\t\tAuto create a host server.",GAME_ARGS[GAME_ARG_SERVER]);
@ -377,7 +383,7 @@ int mainSetup(int argc, char **argv) {
if(knownArgCount != GAME_ARG_END) {
char szBuf[1024]="";
sprintf(szBuf,"Internal arg count mismatch knownArgCount = %d, GAME_ARG_END = %d",knownArgCount,GAME_ARG_END);
throw runtime_error("");
throw runtime_error(szBuf);
}
if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_OPENGL_INFO]) == true ||

View File

@ -55,7 +55,7 @@ public:
~XmlIo();
void cleanup();
XmlNode *load(const string &path, std::map<string,string> mapTagReplacementValues);
XmlNode *load(const string &path, std::map<string,string> mapTagReplacementValues,bool noValidation=false);
void save(const string &path, const XmlNode *node);
};
@ -76,7 +76,7 @@ public:
~XmlTree();
void init(const string &name);
void load(const string &path, std::map<string,string> mapTagReplacementValues);
void load(const string &path, std::map<string,string> mapTagReplacementValues, bool noValidation=false);
void save(const string &path);
XmlNode *getRootNode() const {return rootNode;}

View File

@ -103,22 +103,52 @@ XmlIo::~XmlIo() {
cleanup();
}
XmlNode *XmlIo::load(const string &path, std::map<string,string> mapTagReplacementValues) {
XmlNode *XmlIo::load(const string &path, std::map<string,string> mapTagReplacementValues,bool noValidation) {
try {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("XERCES_FULLVERSIONDOT [%s]\nnoValidation = %d\npath [%s]\n",XERCES_FULLVERSIONDOT,noValidation,path.c_str());
try{
ErrorHandler errorHandler;
#if XERCES_VERSION_MAJOR < 3
DOMBuilder *parser= (static_cast<DOMImplementationLS*>(implementation))->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0);
parser->setErrorHandler(&errorHandler);
parser->setFeature(XMLUni::fgXercesSchema, true);
parser->setFeature(XMLUni::fgXercesSchemaFullChecking, true);
parser->setFeature(XMLUni::fgDOMValidation, true);
if(noValidation == false) {
parser->setFeature(XMLUni::fgXercesSchema, true);
parser->setFeature(XMLUni::fgXercesSchemaFullChecking, true);
//parser->setFeature(XMLUni::fgDOMValidateIfSchema, true);
parser->setFeature(XMLUni::fgDOMValidation, true);
}
else {
//parser->setFeature(XMLUni::fgSAX2CoreValidation, false);
//parser->setFeature(XMLUni::fgXercesDynamic, true);
//parser->setFeature(XMLUni::fgXercesSchema, false);
//parser->setFeature(XMLUni::fgXercesSchemaFullChecking, false);
//parser->setFeature(XMLUni::fgDOMValidateIfSchema, true);
//parser->setFeature(XMLUni::fgDOMValidation, false);
parser->setFeature(XMLUni::fgXercesSchemaFullChecking, false);
parser->setFeature(XMLUni::fgXercesLoadExternalDTD, false);
parser->setFeature(XMLUni::fgXercesCacheGrammarFromParse, true);
parser->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true);
}
#else
DOMLSParser *parser = (static_cast<DOMImplementationLS*>(implementation))->createLSParser(DOMImplementationLS::MODE_SYNCHRONOUS, 0);
DOMConfiguration *config = parser->getDomConfig();
config->setParameter(XMLUni::fgXercesSchema, true);
config->setParameter(XMLUni::fgXercesSchemaFullChecking, true);
config->setParameter(XMLUni::fgDOMValidate, true);
if(noValidation == false) {
config->setParameter(XMLUni::fgXercesSchema, true);
config->setParameter(XMLUni::fgXercesSchemaFullChecking, true);
//config->setParameter(XMLUni::fgDOMValidateIfSchema, true);
config->setParameter(XMLUni::fgDOMValidate, true);
}
else {
config->setParameter(XMLUni::fgXercesSchema, false);
config->setParameter(XMLUni::fgXercesSchemaFullChecking, false);
//config->setParameter(XMLUni::fgDOMValidateIfSchema, true);
config->setParameter(XMLUni::fgDOMValidate, false);
config->setParameter(XMLUni::fgSAX2CoreValidation, true);
config->setParameter(XMLUni::fgXercesDynamic, true);
}
#endif
XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *document= parser->parseURI(path.c_str());
#ifdef WIN32
@ -200,7 +230,7 @@ typedef std::vector<XmlTree*> LoadStack;
//static LoadStack loadStack;
static string loadStackCacheName = string(__FILE__) + string("_loadStackCacheName");
void XmlTree::load(const string &path, std::map<string,string> mapTagReplacementValues) {
void XmlTree::load(const string &path, std::map<string,string> mapTagReplacementValues, bool noValidation) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str());
//printf("XmlTree::load p [%p]\n",this);
@ -219,7 +249,7 @@ void XmlTree::load(const string &path, std::map<string,string> mapTagReplacement
safeMutex.ReleaseLock();
loadPath = path;
this->rootNode= XmlIo::getInstance().load(path, mapTagReplacementValues);
this->rootNode= XmlIo::getInstance().load(path, mapTagReplacementValues, noValidation);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str());
}