From a7e45eb354ddd5688cd9106756b397c4dac811ea Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Tue, 20 Mar 2012 04:53:26 +0000 Subject: [PATCH] - added the ability to record all game command to a replay file. To test saving / loading games from a replay file, add this to glestuser.ini: SaveCommandsForReplay=true --- source/glest_game/game/commander.cpp | 132 ++++++------ source/glest_game/game/commander.h | 10 +- source/glest_game/game/game.cpp | 187 ++++++++++++---- source/glest_game/game/game.h | 4 + .../glest_game/network/client_interface.cpp | 201 ------------------ source/glest_game/network/client_interface.h | 1 + source/glest_game/network/network_interface.h | 1 + source/glest_game/network/network_types.cpp | 38 +++- source/glest_game/network/network_types.h | 4 +- .../glest_game/network/server_interface.cpp | 1 + source/glest_game/network/server_interface.h | 2 + source/glest_game/type_instances/unit.cpp | 2 +- source/glest_game/types/faction_type.cpp | 20 ++ source/glest_game/types/faction_type.h | 1 + source/glest_game/types/unit_type.cpp | 10 +- source/glest_game/world/unit_updater.cpp | 4 + source/shared_lib/include/xml/xml_parser.h | 2 + source/shared_lib/sources/xml/xml_parser.cpp | 4 + 18 files changed, 301 insertions(+), 323 deletions(-) diff --git a/source/glest_game/game/commander.cpp b/source/glest_game/game/commander.cpp index ee8b6ab7..ac2d0a36 100644 --- a/source/glest_game/game/commander.cpp +++ b/source/glest_game/game/commander.cpp @@ -533,26 +533,46 @@ CommandResult Commander::pushNetworkCommand(const NetworkCommand* networkCommand } void Commander::signalNetworkUpdate(Game *game) { - updateNetwork(game); -/* - if(this->networkThread != NULL) { - this->game = game; - this->networkThread->signalUpdate(1); - - time_t elapsedWait = time(NULL); - for(;difftime(time(NULL),elapsedWait) <= 4 && - this->networkThread->isSignalCompleted(1) == false;) { - game->render(); - } - } -*/ } void Commander::commanderNetworkUpdateTask(int id) { //updateNetwork(game); } +bool Commander::getReplayCommandListForFrame(int worldFrameCount) { + bool haveReplyCommands = false; + if(replayCommandList.empty() == false) { + //int worldFrameCount = world->getFrameCount(); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("worldFrameCount = %d replayCommandList.size() = %lu\n",worldFrameCount,replayCommandList.size()); + + std::vector replayList; + for(unsigned int i = 0; i < replayCommandList.size(); ++i) { + std::pair &cmd = replayCommandList[i]; + if(cmd.first <= worldFrameCount) { + replayList.push_back(cmd.second); + haveReplyCommands = true; + } + } + if(haveReplyCommands == true) { + replayCommandList.erase(replayCommandList.begin(),replayCommandList.begin() + replayList.size()); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("worldFrameCount = %d GIVING COMMANDS replayList.size() = %lu\n",worldFrameCount,replayList.size()); + for(int i= 0; i < replayList.size(); ++i){ + giveNetworkCommand(&replayList[i]); + //pushNetworkCommand(&replayList[i]); + } + GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); + gameNetworkInterface->setKeyframe(worldFrameCount); + } + } + return haveReplyCommands; +} + +bool Commander::hasReplayCommandListForFrame() const { + return (replayCommandList.empty() == false); +} + void Commander::updateNetwork(Game *game) { NetworkManager &networkManager= NetworkManager::getInstance(); @@ -564,62 +584,30 @@ void Commander::updateNetwork(Game *game) { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] networkManager.isNetworkGame() = %d,world->getFrameCount() = %d, gameSettings->getNetworkFramePeriod() = %d\n",__FILE__,__FUNCTION__,__LINE__,networkManager.isNetworkGame(),world->getFrameCount(),gameSettings->getNetworkFramePeriod()); - GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); + //std::vector replayList = getReplayCommandListForFrame(); + if(getReplayCommandListForFrame(world->getFrameCount()) == false) { + GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) perfTimer.start(); - //update the keyframe - gameNetworkInterface->updateKeyframe(world->getFrameCount()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && perfTimer.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] gameNetworkInterface->updateKeyframe for %d took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,world->getFrameCount(),perfTimer.getMillis()); + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) perfTimer.start(); + //update the keyframe + gameNetworkInterface->updateKeyframe(world->getFrameCount()); + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && perfTimer.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] gameNetworkInterface->updateKeyframe for %d took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,world->getFrameCount(),perfTimer.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) perfTimer.start(); - //give pending commands - for(int i= 0; i < gameNetworkInterface->getPendingCommandCount(); ++i){ - giveNetworkCommand(gameNetworkInterface->getPendingCommand(i)); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && perfTimer.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] giveNetworkCommand took %lld msecs, PendingCommandCount = %d\n",__FILE__,__FUNCTION__,__LINE__,perfTimer.getMillis(),gameNetworkInterface->getPendingCommandCount()); - gameNetworkInterface->clearPendingCommands(); + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) perfTimer.start(); + //give pending commands + for(int i= 0; i < gameNetworkInterface->getPendingCommandCount(); ++i){ + giveNetworkCommand(gameNetworkInterface->getPendingCommand(i)); + } + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && perfTimer.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] giveNetworkCommand took %lld msecs, PendingCommandCount = %d\n",__FILE__,__FUNCTION__,__LINE__,perfTimer.getMillis(),gameNetworkInterface->getPendingCommandCount()); + gameNetworkInterface->clearPendingCommands(); + } } } } -/* -void Commander::giveNetworkCommandSpecial(const NetworkCommand* networkCommand) const { - switch(networkCommand->getNetworkCommandType()) { - case nctNetworkCommand: { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctNetworkCommand\n",__FILE__,__FUNCTION__,__LINE__); - switch(networkCommand->getCommandTypeId()) { - case ncstRotateUnit: { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found ncstRotateUnit [%d]\n",__FILE__,__FUNCTION__,__LINE__,networkCommand->getTargetId()); - - int unitTypeId = networkCommand->getUnitId(); - int factionIndex = networkCommand->getUnitTypeId(); - int rotateAmount = networkCommand->getTargetId(); - - //const Faction *faction = world->getFaction(factionIndex); - //const UnitType* unitType= world->findUnitTypeById(faction->getType(), factionIndex); - - char unitKey[50]=""; - sprintf(unitKey,"%d_%d",unitTypeId,factionIndex); - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unitKey = [%s]\n",__FILE__,__FUNCTION__,__LINE__,unitKey); - - Game *game = this->world->getGame(); - Gui *gui = game->getGui(); - gui->setUnitTypeBuildRotation(unitKey,rotateAmount); - //unit->setRotateAmount(networkCommand->getTargetId()); - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found ncstRotateUnit [%d]\n",__FILE__,__FUNCTION__,__LINE__,networkCommand->getTargetId()); - } - break; - } - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctNetworkCommand\n",__FILE__,__FUNCTION__,__LINE__); - } - break; - default: - assert(false); - } +void Commander::addToReplayCommandList(NetworkCommand &command,int worldFrameCount) { + replayCommandList.push_back(make_pair(worldFrameCount,command)); } -*/ void Commander::giveNetworkCommand(NetworkCommand* networkCommand) const { @@ -628,6 +616,9 @@ void Commander::giveNetworkCommand(NetworkCommand* networkCommand) const { if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld [START]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + + world->getGame()->addNetworkCommandToReplayList(networkCommand,world->getFrameCount()); + networkCommand->preprocessNetworkCommand(this->world); if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld [after networkCommand->preprocessNetworkCommand]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); @@ -833,6 +824,7 @@ void Commander::giveNetworkCommand(NetworkCommand* networkCommand) const { if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld [after world->findUnitById]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Running command NetworkCommandType = %d, unitid = %d [%p] factionindex = %d\n",networkCommand->getNetworkCommandType(),networkCommand->getUnitId(),unit,(unit != NULL ? unit->getFactionIndex() : -1)); //execute command, if unit is still alive if(unit != NULL) { switch(networkCommand->getNetworkCommandType()) { @@ -906,6 +898,9 @@ Command* Commander::buildCommand(const NetworkCommand* networkCommand) const { if(unit == NULL) { char szBuf[1024]=""; sprintf(szBuf,"In [%s::%s Line: %d] Can not find unit with id: %d. Game out of synch.",__FILE__,__FUNCTION__,__LINE__,networkCommand->getUnitId()); + SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",szBuf); + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",szBuf); + GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); if(gameNetworkInterface != NULL) { char szMsg[1024]=""; @@ -919,7 +914,8 @@ Command* Commander::buildCommand(const NetworkCommand* networkCommand) const { ct= unit->getType()->findCommandTypeById(networkCommand->getCommandTypeId()); if(unit->getFaction()->getIndex() != networkCommand->getUnitFactionIndex()) { - char szBuf[4096]=""; + + char szBuf[10400]=""; sprintf(szBuf,"In [%s::%s Line: %d]\nUnit / Faction mismatch for network command = [%s]\n%s\nfor unit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.", __FILE__,__FUNCTION__,__LINE__,networkCommand->toString().c_str(),unit->getType()->getCommandTypeListDesc().c_str(),unit->getId(), unit->getFullName().c_str(),unit->getDesc().c_str(),unit->getFaction()->getIndex()); @@ -981,11 +977,14 @@ Command* Commander::buildCommand(const NetworkCommand* networkCommand) const { //validate command type if(ct == NULL) { - char szBuf[4096]=""; - sprintf(szBuf,"In [%s::%s Line: %d]\nCan not find command type for network command = [%s]\n%s\nfor unit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.", - __FILE__,__FUNCTION__,__LINE__,networkCommand->toString().c_str(),unit->getType()->getCommandTypeListDesc().c_str(),unit->getId(), unit->getFullName().c_str(),unit->getDesc().c_str(),unit->getFaction()->getIndex()); + char szBuf[10400]=""; + sprintf(szBuf,"In [%s::%s Line: %d]\nCan not find command type for network command = [%s]\n%s\nfor unit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nUnit Type Info:\n[%s]\nNetwork unit type:\n[%s]\nGame out of synch.", + __FILE__,__FUNCTION__,__LINE__,networkCommand->toString().c_str(),unit->getType()->getCommandTypeListDesc().c_str(), + unit->getId(), unit->getFullName().c_str(),unit->getDesc().c_str(),unit->getFaction()->getIndex(),unit->getType()->toString().c_str(), + (unitType != NULL ? unitType->getName().c_str() : "null")); SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",szBuf); + SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",szBuf); //std::string worldLog = world->DumpWorldToLog(); world->DumpWorldToLog(); @@ -997,6 +996,7 @@ Command* Commander::buildCommand(const NetworkCommand* networkCommand) const { } std::string sError = "Error [#3]: Game is out of sync, please check log files for details."; + abort(); throw runtime_error(sError); } diff --git a/source/glest_game/game/commander.h b/source/glest_game/game/commander.h index 37049984..07313db9 100644 --- a/source/glest_game/game/commander.h +++ b/source/glest_game/game/commander.h @@ -80,6 +80,7 @@ private: //CommanderNetworkThread *networkThread; //Game *game; + std::vector > replayCommandList; public: Commander(); @@ -89,6 +90,10 @@ public: void init(World *world); void updateNetwork(Game *game); + void addToReplayCommandList(NetworkCommand &command,int worldFrameCount); + bool getReplayCommandListForFrame(int worldFrameCount); + bool hasReplayCommandListForFrame() const; + CommandResult tryGiveCommand(const Selection *selection, const CommandType *commandType, const Vec2i &pos, const UnitType* unitType, CardinalDir facing, bool tryQueue,Unit *targetUnit=NULL) const; @@ -104,12 +109,13 @@ public: void tryPauseGame() const; void tryResumeGame() const; - CommandResult pushNetworkCommand(const NetworkCommand* networkCommand) const; - //void giveNetworkCommandSpecial(const NetworkCommand* networkCommand) const; Command* buildCommand(const NetworkCommand* networkCommand) const; private: + CommandResult pushNetworkCommand(const NetworkCommand* networkCommand) const; + //void giveNetworkCommandSpecial(const NetworkCommand* networkCommand) const; + CommandResult computeResult(const CommandResultContainer &results) const; void giveNetworkCommand(NetworkCommand* networkCommand) const; diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index eae182ce..7a17d016 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -112,8 +112,11 @@ Game::Game() : ProgramState(NULL) { //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); loadGameNode = NULL; + xmlTreeSaveGame = NULL; + lastworldFrameCountForReplay = -1; lastNetworkPlayerConnectionCheck = time(NULL); + fadeMusicMilliseconds = Config::getInstance().getInt("GameStartStopFadeSoundMilliseconds",intToStr(fadeMusicMilliseconds).c_str()); GAME_STATS_DUMP_INTERVAL = Config::getInstance().getInt("GameStatsDumpIntervalSeconds",intToStr(GAME_STATS_DUMP_INTERVAL).c_str()); } @@ -186,6 +189,8 @@ void Game::resetMembers() { //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); loadGameNode = NULL; + xmlTreeSaveGame = NULL; + lastworldFrameCountForReplay = -1; lastNetworkPlayerConnectionCheck = time(NULL); @@ -321,6 +326,9 @@ Game::~Game() { world.end(); //must die before selection because of referencers + delete xmlTreeSaveGame; + xmlTreeSaveGame = NULL; + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] aiInterfaces.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,aiInterfaces.size()); // MUST DO THIS LAST!!!! Because objects above have pointers to things like @@ -1199,57 +1207,62 @@ void Game::update() { world.getStats()->addFramesToCalculatePlaytime(); //update - for(int i = 0; i < updateLoops; ++i) { - chrono.start(); - //AiInterface - for(int j = 0; j < world.getFactionCount(); ++j) { - Faction *faction = world.getFaction(j); - if( faction->getCpuControl(enableServerControlledAI,isNetworkGame,role) == true && - scriptManager.getPlayerModifiers(j)->getAiEnabled() == true) { + do { + for(int i = 0; i < updateLoops; ++i) { + chrono.start(); + //AiInterface + if(commander.hasReplayCommandListForFrame() == false) { + for(int j = 0; j < world.getFactionCount(); ++j) { + Faction *faction = world.getFaction(j); + if( faction->getCpuControl(enableServerControlledAI,isNetworkGame,role) == true && + scriptManager.getPlayerModifiers(j)->getAiEnabled() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] [i = %d] faction = %d, factionCount = %d, took msecs: %lld [before AI updates]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,j,world.getFactionCount(),chrono.getMillis()); + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] [i = %d] faction = %d, factionCount = %d, took msecs: %lld [before AI updates]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,j,world.getFactionCount(),chrono.getMillis()); - aiInterfaces[j]->update(); + aiInterfaces[j]->update(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] [i = %d] faction = %d, factionCount = %d, took msecs: %lld [after AI updates]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,j,world.getFactionCount(),chrono.getMillis()); + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] [i = %d] faction = %d, factionCount = %d, took msecs: %lld [after AI updates]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,j,world.getFactionCount(),chrono.getMillis()); + } + } } + + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [AI updates]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + //World + world.update(); + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [world update i = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),i); + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + // Commander + //commander.updateNetwork(); + commander.signalNetworkUpdate(this); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [commander updateNetwork i = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),i); + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + //Gui + gui.update(); + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [gui updating i = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),i); + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + //Particle systems + if(weatherParticleSystem != NULL) { + weatherParticleSystem->setPos(gameCamera.getPos()); + } + + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [weather particle updating i = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),i); + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + Renderer &renderer= Renderer::getInstance(); + renderer.updateParticleManager(rsGame,avgRenderFps); + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [particle manager updating i = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),i); + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + //good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [AI updates]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - //World - world.update(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [world update i = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),i); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - // Commander - //commander.updateNetwork(); - commander.signalNetworkUpdate(this); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [commander updateNetwork i = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),i); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - //Gui - gui.update(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [gui updating i = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),i); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - //Particle systems - if(weatherParticleSystem != NULL) { - weatherParticleSystem->setPos(gameCamera.getPos()); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [weather particle updating i = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),i); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - Renderer &renderer= Renderer::getInstance(); - renderer.updateParticleManager(rsGame,avgRenderFps); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [particle manager updating i = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),i); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - //good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); } + while (commander.hasReplayCommandListForFrame() == true); } //else if(role == nrClient) { else { @@ -3368,6 +3381,10 @@ void Game::setPaused(bool value,bool forceAllowPauseStateChange) { } int Game::getUpdateLoops() { + if(commander.hasReplayCommandListForFrame() == true) { + return 1; + } + if(paused) { return 0; } @@ -3456,6 +3473,43 @@ void Game::toggleTeamColorMarker() { renderExtraTeamColor=renderExtraTeamColor%4; } +void Game::addNetworkCommandToReplayList(NetworkCommand* networkCommand, int worldFrameCount) { + Config &config= Config::getInstance(); + if(config.getBool("SaveCommandsForReplay","false") == true) { + std::map mapTagReplacements; + if(xmlTreeSaveGame == NULL) { + xmlTreeSaveGame = new XmlTree(XML_RAPIDXML_ENGINE); + + xmlTreeSaveGame->init("megaglest-saved-game"); + XmlNode *rootNode = xmlTreeSaveGame->getRootNode(); + + std::map mapTagReplacements; + time_t now = time(NULL); + struct tm *loctime = localtime (&now); + char szBuf[4096]=""; + strftime(szBuf,4095,"%Y-%m-%d %H:%M:%S",loctime); + + rootNode->addAttribute("version",glestVersionString, mapTagReplacements); + rootNode->addAttribute("timestamp",szBuf, mapTagReplacements); + + XmlNode *gameNode = rootNode->addChild("Game"); + } + + XmlNode *rootNode = xmlTreeSaveGame->getRootNode(); + XmlNode *gameNode = rootNode->getChild("Game"); + if(gameNode->hasAttribute("LastWorldFrameCount") == false) { + gameNode->addAttribute("LastWorldFrameCount",intToStr(worldFrameCount), mapTagReplacements); + } + else { + XmlAttribute *lastworldFrameCountAttr = gameNode->getAttribute("LastWorldFrameCount"); + lastworldFrameCountAttr->setValue(intToStr(worldFrameCount)); + } + + XmlNode *networkCommandNode = networkCommand->saveGame(gameNode); + networkCommandNode->addAttribute("worldFrameCount",intToStr(worldFrameCount), mapTagReplacements); + } +} + string Game::saveGame(string name) { Config &config= Config::getInstance(); // auto name file if using saved file pattern string @@ -3635,6 +3689,12 @@ string Game::saveGame(string name) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Saving game to [%s]\n",saveGameFile.c_str()); xmlTree.save(saveGameFile); + if(xmlTreeSaveGame != NULL) { + string replayFile = saveGameFile + ".replay"; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Saving game replay commands to [%s]\n",replayFile.c_str()); + xmlTreeSaveGame->save(replayFile); + } + if(masterserverMode == false) { // take Screenshot string jpgFileName=saveGameFile+".jpg"; @@ -3681,6 +3741,43 @@ void Game::loadGame(string name,Program *programPtr,bool isMasterserverMode) { networkManager.init(nrServer,true); Game *newGame = new Game(programPtr, &newGameSettings, isMasterserverMode); + + Config &config= Config::getInstance(); + // This condition will re-play all the commands from a replay file + // INSTEAD of saving from a saved game. + if(config.getBool("SaveCommandsForReplay","false") == true) { + XmlTree xmlTreeReplay(XML_RAPIDXML_ENGINE); + std::map mapExtraTagReplacementValues; + xmlTreeReplay.load(name + ".replay", Properties::getTagReplacementValues(&mapExtraTagReplacementValues),true); + + const XmlNode *rootNode= xmlTreeReplay.getRootNode(); + 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->lastworldFrameCountForReplay = gameNode->getAttribute("LastWorldFrameCount")->getIntValue(); + + vector networkCommandNodeList = gameNode->getChildList("NetworkCommand"); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("networkCommandNodeList.size() = %lu\n",networkCommandNodeList.size()); + for(unsigned int i = 0; i < networkCommandNodeList.size(); ++i) { + XmlNode *node = networkCommandNodeList[i]; + int worldFrameCount = node->getAttribute("worldFrameCount")->getIntValue(); + NetworkCommand command; + command.loadGame(node); + newGame->commander.addToReplayCommandList(command,worldFrameCount); + } + + programPtr->setState(newGame); + return; + } + newGame->loadGameNode = gameNode; // newGame->mouse2d = gameNode->getAttribute("mouse2d")->getIntValue(); diff --git a/source/glest_game/game/game.h b/source/glest_game/game/game.h index 8abe527d..beb37bee 100644 --- a/source/glest_game/game/game.h +++ b/source/glest_game/game/game.h @@ -149,7 +149,9 @@ private: time_t lastMasterServerGameStatsDump; + XmlTree *xmlTreeSaveGame; XmlNode *loadGameNode; + int lastworldFrameCountForReplay; public: Game(); @@ -232,6 +234,8 @@ public: string saveGame(string name); static void loadGame(string name,Program *programPtr,bool isMasterserverMode); + void addNetworkCommandToReplayList(NetworkCommand* networkCommand,int worldFrameCount); + private: //render void render3d(); diff --git a/source/glest_game/network/client_interface.cpp b/source/glest_game/network/client_interface.cpp index 23f4417e..59bc7a4c 100644 --- a/source/glest_game/network/client_interface.cpp +++ b/source/glest_game/network/client_interface.cpp @@ -818,210 +818,9 @@ void ClientInterface::updateKeyframe(int frameCount) { } bool hasData = getNetworkCommand(frameCount,cachedPendingCommandsIndex); - // if(hasData == true) { - // MutexSafeWrapper safeMutex(networkCommandListThreadAccessor,CODE_AT_LINE); - // - // Commands &frameCmdList = cachedPendingCommands[frameCount]; - // for(int i= 0; i < frameCmdList.size(); ++i) { - // pendingCommands.push_back(frameCmdList[i]); - // } - // cachedPendingCommands.erase(frameCount); - // } } } -// int simulateLag = Config::getInstance().getInt("SimulateClientLag","0"); -// bool done= false; -// while(done == false) { -// //wait for the next message -// NetworkMessageType networkMessageType = waitForMessage(); -// -// // START: Test simulating lag for the client -// if(simulateLag > 0) { -// if(clientSimulationLagStartTime == 0) { -// clientSimulationLagStartTime = time(NULL); -// } -// if(difftime(time(NULL),clientSimulationLagStartTime) <= Config::getInstance().getInt("SimulateClientLagDurationSeconds","0")) { -// sleep(Config::getInstance().getInt("SimulateClientLag","0")); -// } -// } -// // END: Test simulating lag for the client -// -// //check we have an expected message -// //NetworkMessageType networkMessageType= getNextMessageType(); -// -// switch(networkMessageType) -// { -// case nmtCommandList: -// { -// -// int waitCount = 0; -// //make sure we read the message -// time_t receiveTimeElapsed = time(NULL); -// NetworkMessageCommandList networkMessageCommandList; -// bool gotCmd = receiveMessage(&networkMessageCommandList); -// if(gotCmd == false) { -// throw runtime_error("error retrieving nmtCommandList returned false!"); -// } -// -//// while(receiveMessage(&networkMessageCommandList) == false && -//// isConnected() == true && -//// difftime(time(NULL),receiveTimeElapsed) <= (messageWaitTimeout / 2000)) { -//// waitCount++; -//// } -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] receiveMessage took %lld msecs, waitCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),waitCount); -// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); -// //check that we are in the right frame -// if(networkMessageCommandList.getFrameCount() != frameCount) { -// string sErr = "Player: " + getHumanPlayerName() + -// " got a Network synchronization error, frame counts do not match, server frameCount = " + -// intToStr(networkMessageCommandList.getFrameCount()) + ", local frameCount = " + -// intToStr(frameCount); -// sendTextMessage(sErr,-1, true,""); -// DisplayErrorMessage(sErr); -// sleep(1); -// -// quit= true; -// close(); -// return; -// } -// -// // give all commands -// for(int i= 0; i < networkMessageCommandList.getCommandCount(); ++i) { -// pendingCommands.push_back(*networkMessageCommandList.getCommand(i)); -// } -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] transfer network commands took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); -// -// done= true; -// } -// break; -// -// case nmtPing: -// { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtPing\n",__FILE__,__FUNCTION__); -// -// NetworkMessagePing networkMessagePing; -// if(receiveMessage(&networkMessagePing)) { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -// lastPingInfo = networkMessagePing; -// } -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); -// } -// break; -// -// case nmtQuit: -// { -// time_t receiveTimeElapsed = time(NULL); -// NetworkMessageQuit networkMessageQuit; -//// while(receiveMessage(&networkMessageQuit) == false && -//// isConnected() == true && -//// difftime(time(NULL),receiveTimeElapsed) <= (messageWaitTimeout / 2000)) { -//// } -// bool gotCmd = receiveMessage(&networkMessageQuit); -// if(gotCmd == false) { -// throw runtime_error("error retrieving nmtQuit returned false!"); -// } -// -// quit= true; -// done= true; -// } -// break; -// -// case nmtText: -// { -// time_t receiveTimeElapsed = time(NULL); -// NetworkMessageText networkMessageText; -//// while(receiveMessage(&networkMessageText) == false && -//// isConnected() == true && -//// difftime(time(NULL),receiveTimeElapsed) <= (messageWaitTimeout / 1000)) { -//// } -// bool gotCmd = receiveMessage(&networkMessageText); -// if(gotCmd == false) { -// throw runtime_error("error retrieving nmtText returned false!"); -// } -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); -// -// ChatMsgInfo msg(networkMessageText.getText().c_str(),networkMessageText.getTeamIndex(),networkMessageText.getPlayerIndex(),networkMessageText.getTargetLanguage()); -// this->addChatInfo(msg); -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); -// } -// break; -// -// case nmtLaunch: -// case nmtBroadCastSetup: -// { -// NetworkMessageLaunch networkMessageLaunch; -// if(receiveMessage(&networkMessageLaunch)) { -// if(networkMessageLaunch.getMessageType() == nmtLaunch) { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got nmtLaunch\n",__FILE__,__FUNCTION__,__LINE__); -// } -// else if(networkMessageLaunch.getMessageType() == nmtBroadCastSetup) { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got nmtBroadCastSetup\n",__FILE__,__FUNCTION__,__LINE__); -// } -// else { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got networkMessageLaunch.getMessageType() = %d\n",__FILE__,__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType()); -// -// char szBuf[1024]=""; -// snprintf(szBuf,1023,"In [%s::%s Line: %d] Invalid networkMessageLaunch.getMessageType() = %d",__FILE__,__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType()); -// throw runtime_error(szBuf); -// } -// -// networkMessageLaunch.buildGameSettings(&gameSettings); -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got networkMessageLaunch.getMessageType() = %d\n",__FILE__,__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType()); -// //replace server player by network -// for(int i= 0; i 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); //printf("In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); } diff --git a/source/glest_game/network/client_interface.h b/source/glest_game/network/client_interface.h index 05652376..b62d7290 100644 --- a/source/glest_game/network/client_interface.h +++ b/source/glest_game/network/client_interface.h @@ -75,6 +75,7 @@ public: virtual void update(); virtual void updateLobby(); virtual void updateKeyframe(int frameCount); + virtual void setKeyframe(int frameCount) { currentFrameCount = frameCount; } virtual void waitUntilReady(Checksum* checksum); // message sending diff --git a/source/glest_game/network/network_interface.h b/source/glest_game/network/network_interface.h index 27ae42d1..6ef5a413 100644 --- a/source/glest_game/network/network_interface.h +++ b/source/glest_game/network/network_interface.h @@ -186,6 +186,7 @@ public: virtual void update()= 0; virtual void updateLobby()= 0; virtual void updateKeyframe(int frameCount)= 0; + virtual void setKeyframe(int frameCount)= 0; virtual void waitUntilReady(Checksum* checksum)= 0; //message sending diff --git a/source/glest_game/network/network_types.cpp b/source/glest_game/network/network_types.cpp index 1417b07c..3b1d36e3 100644 --- a/source/glest_game/network/network_types.cpp +++ b/source/glest_game/network/network_types.cpp @@ -98,7 +98,7 @@ string NetworkCommand::toString() const { return result; } -void NetworkCommand::saveGame(XmlNode *rootNode) { +XmlNode * NetworkCommand::saveGame(XmlNode *rootNode) { std::map mapTagReplacements; XmlNode *networkCommandNode = rootNode->addChild("NetworkCommand"); @@ -130,5 +130,41 @@ void NetworkCommand::saveGame(XmlNode *rootNode) { networkCommandNode->addAttribute("commandStateValue",intToStr(commandStateValue), mapTagReplacements); // int32 unitCommandGroupId; networkCommandNode->addAttribute("unitCommandGroupId",intToStr(unitCommandGroupId), mapTagReplacements); + + return networkCommandNode; } + +void NetworkCommand::loadGame(const XmlNode *rootNode) { + const XmlNode *networkCommandNode = rootNode; + +// int16 networkCommandType; + networkCommandType = networkCommandNode->getAttribute("networkCommandType")->getIntValue(); +// int32 unitId; + unitId = networkCommandNode->getAttribute("unitId")->getIntValue(); +// int16 unitTypeId; + unitTypeId = networkCommandNode->getAttribute("unitTypeId")->getIntValue(); +// int16 commandTypeId; + commandTypeId = networkCommandNode->getAttribute("commandTypeId")->getIntValue(); +// int16 positionX; + positionX = networkCommandNode->getAttribute("positionX")->getIntValue(); +// int16 positionY; + positionY = networkCommandNode->getAttribute("positionY")->getIntValue(); +// int32 targetId; + targetId = networkCommandNode->getAttribute("targetId")->getIntValue(); +// int8 wantQueue; + wantQueue = networkCommandNode->getAttribute("wantQueue")->getIntValue(); +// int8 fromFactionIndex; + fromFactionIndex = networkCommandNode->getAttribute("fromFactionIndex")->getIntValue(); +// uint16 unitFactionUnitCount; + unitFactionUnitCount = networkCommandNode->getAttribute("unitFactionUnitCount")->getIntValue(); +// int8 unitFactionIndex; + unitFactionIndex = networkCommandNode->getAttribute("unitFactionIndex")->getIntValue(); +// int8 commandStateType; + commandStateType = networkCommandNode->getAttribute("commandStateType")->getIntValue(); +// int32 commandStateValue; + commandStateValue = networkCommandNode->getAttribute("commandStateValue")->getIntValue(); +// int32 unitCommandGroupId; + unitCommandGroupId = networkCommandNode->getAttribute("unitCommandGroupId")->getIntValue(); +} + }}//end namespace diff --git a/source/glest_game/network/network_types.h b/source/glest_game/network/network_types.h index 009868ad..183c1038 100644 --- a/source/glest_game/network/network_types.h +++ b/source/glest_game/network/network_types.h @@ -131,8 +131,8 @@ public: void preprocessNetworkCommand(World *world); string toString() const; - void saveGame(XmlNode *rootNode); - + XmlNode * saveGame(XmlNode *rootNode); + void loadGame(const XmlNode *rootNode); }; #pragma pack(pop) diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index 3a163d6c..ef7e4fdf 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -1213,6 +1213,7 @@ void ServerInterface::updateKeyframe(int frameCount) { currentFrameCount = frameCount; if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] currentFrameCount = %d, requestedCommands.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,currentFrameCount,requestedCommands.size()); NetworkMessageCommandList networkMessageCommandList(frameCount); + while(requestedCommands.empty() == false) { if(networkMessageCommandList.addCommand(&requestedCommands.back())) { pendingCommands.push_back(requestedCommands.back()); diff --git a/source/glest_game/network/server_interface.h b/source/glest_game/network/server_interface.h index 5a46477d..e2eae607 100644 --- a/source/glest_game/network/server_interface.h +++ b/source/glest_game/network/server_interface.h @@ -102,6 +102,8 @@ public: virtual void update(); virtual void updateLobby() { }; virtual void updateKeyframe(int frameCount); + virtual void setKeyframe(int frameCount) { currentFrameCount = frameCount; } + virtual void waitUntilReady(Checksum *checksum); virtual void sendTextMessage(const string & text, int teamIndex, bool echoLocal, string targetLanguage); void sendTextMessage(const string & text, int teamIndex, bool echoLocal, string targetLanguage, int lockedSlotIndex); diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index f58cb6fd..9b9696a8 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -1370,7 +1370,7 @@ CommandResult Unit::giveCommand(Command *command, bool tryQueue) { CommandResult result= checkCommand(command); if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] checkCommand returned: [%d]\n",__FILE__,__FUNCTION__,__LINE__,result); - //printf("In [%s::%s] Line: %d check command returned %d, commands.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,result,commands.size()); + //printf("In [%s::%s] Line: %d check command returned %d, commands.size() = %d\n[%s]\n\n",__FILE__,__FUNCTION__,__LINE__,result,commands.size(),command->toString().c_str()); if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); diff --git a/source/glest_game/types/faction_type.cpp b/source/glest_game/types/faction_type.cpp index 1df695a9..c9398016 100644 --- a/source/glest_game/types/faction_type.cpp +++ b/source/glest_game/types/faction_type.cpp @@ -726,6 +726,26 @@ const UnitType *FactionType::getUnitType(const string &name) const{ throw runtime_error("Unit type not found: [" + name + "] in faction type [" + this->name + "]"); } +const UnitType *FactionType::getUnitTypeById(int id) const{ + for(int i=0; iname + "]"); +} + const UpgradeType *FactionType::getUpgradeType(const string &name) const{ for(int i=0; itoString(); } - result += " commandTypes:"; + result += " commandTypes: [" + intToStr(commandTypes.size()) + "]"; for(int i = 0; i < commandTypes.size(); ++i) { result += " i = " + intToStr(i) + " " + commandTypes[i]->toString(); } - result += " storedResources:"; + result += " storedResources: [" + intToStr(storedResources.size()) + "]"; for(int i = 0; i < storedResources.size(); ++i) { result += " i = " + intToStr(i) + " " + storedResources[i].getDescription(); } - result += " levels:"; + result += " levels: [" + intToStr(levels.size()) + "]"; for(int i = 0; i < levels.size(); ++i) { result += " i = " + intToStr(i) + " " + levels[i].getName(); } diff --git a/source/glest_game/world/unit_updater.cpp b/source/glest_game/world/unit_updater.cpp index 0ad1fe09..fabc1230 100644 --- a/source/glest_game/world/unit_updater.cpp +++ b/source/glest_game/world/unit_updater.cpp @@ -153,6 +153,8 @@ void UnitUpdater::updateUnit(Unit *unit) { if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after unit->update()]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + //printf("Update Unit [%d - %s] = %d\n",unit->getId(),unit->getType()->getName().c_str(),update); + //update unit if(update == true) { //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -908,6 +910,8 @@ void UnitUpdater::updateHarvest(Unit *unit, int frameIndex) { if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + //printf("In UpdateHarvest [%d - %s] unit->getCurrSkill()->getClass() = %d\n",unit->getId(),unit->getType()->getName().c_str(),unit->getCurrSkill()->getClass()); + if(unit->getCurrSkill()->getClass() != scHarvest) { //if not working if(unit->getLoadCount() == 0) { diff --git a/source/shared_lib/include/xml/xml_parser.h b/source/shared_lib/include/xml/xml_parser.h index 8eb51254..81b17bc5 100644 --- a/source/shared_lib/include/xml/xml_parser.h +++ b/source/shared_lib/include/xml/xml_parser.h @@ -191,6 +191,8 @@ public: float getFloatValue() const; float getFloatValue(float min, float max) const; const string getRestrictedValue(string prefixValue="", bool trimValueWithStartingSlash=false) const; + + void setValue(string val); }; diff --git a/source/shared_lib/sources/xml/xml_parser.cpp b/source/shared_lib/sources/xml/xml_parser.cpp index 79cf38e3..d670382e 100644 --- a/source/shared_lib/sources/xml/xml_parser.cpp +++ b/source/shared_lib/sources/xml/xml_parser.cpp @@ -841,4 +841,8 @@ const string XmlAttribute::getRestrictedValue(string prefixValue, bool trimValue return result; } +void XmlAttribute::setValue(string val) { + value = val; +} + }}//end namespace