diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 8084eee46..3adc9d10f 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -795,7 +795,9 @@ void Game::load(int loadTypes) { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); if(scenarioName.empty() == false) { Lang::getInstance().loadScenarioStrings(gameSettings.getScenarioDir(), scenarioName); - world.loadScenario(gameSettings.getScenarioDir(), &checksum); + + //printf("In [%s::%s Line: %d] rootNode [%p][%s]\n",__FILE__,__FUNCTION__,__LINE__,loadGameNode,(loadGameNode != NULL ? loadGameNode->getName().c_str() : "none")); + world.loadScenario(gameSettings.getScenarioDir(), &checksum, false,loadGameNode); } } @@ -902,7 +904,7 @@ void Game::init(bool initForPreviewOnly) { Window::handleEvent(); SDL_PumpEvents(); - scriptManager.init(&world, &gameCamera); + scriptManager.init(&world, &gameCamera,loadGameNode); //good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); @@ -1422,7 +1424,7 @@ void Game::update() { gameCamera.setCalculatedDefault(map->getMaxMapHeight()+13.0f); } - scriptManager.init(&world, &gameCamera); + scriptManager.init(&world, &gameCamera,loadGameNode); renderer.initGame(this,this->getGameCameraPtr()); //sounds @@ -3632,6 +3634,7 @@ string Game::saveGame(string name) { //Console console; //ChatManager chatManager; //ScriptManager scriptManager; + scriptManager.saveGame(gameNode); //misc //Checksum checksum; diff --git a/source/glest_game/game/script_manager.cpp b/source/glest_game/game/script_manager.cpp index c22c75533..e43add55c 100644 --- a/source/glest_game/game/script_manager.cpp +++ b/source/glest_game/game/script_manager.cpp @@ -44,6 +44,34 @@ public: } }; +ScriptManagerMessage::ScriptManagerMessage() { + this->text= ""; + this->header= ""; + +} + +ScriptManagerMessage::ScriptManagerMessage(string text, string header) { + this->text= text; + this->header= header; +} + +void ScriptManagerMessage::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *scriptManagerMessageNode = rootNode->addChild("ScriptManagerMessage"); + + //string text; + scriptManagerMessageNode->addAttribute("text",text, mapTagReplacements); + //string header; + scriptManagerMessageNode->addAttribute("header",header, mapTagReplacements); +} + +void ScriptManagerMessage::loadGame(const XmlNode *rootNode) { + const XmlNode *scriptManagerMessageNode = rootNode; + + text = scriptManagerMessageNode->getAttribute("text")->getValue(); + header = scriptManagerMessageNode->getAttribute("header")->getValue(); +} + // ===================================================== // class PlayerModifiers // ===================================================== @@ -54,6 +82,89 @@ PlayerModifiers::PlayerModifiers(){ consumeEnabled = true; } +void PlayerModifiers::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *playerModifiersNode = rootNode->addChild("PlayerModifiers"); + + //bool winner; + playerModifiersNode->addAttribute("winner",intToStr(winner), mapTagReplacements); + //bool aiEnabled; + playerModifiersNode->addAttribute("aiEnabled",intToStr(aiEnabled), mapTagReplacements); + //bool consumeEnabled; + playerModifiersNode->addAttribute("consumeEnabled",intToStr(consumeEnabled), mapTagReplacements); +} + +void PlayerModifiers::loadGame(const XmlNode *rootNode) { + const XmlNode *playerModifiersNode = rootNode; + + winner = playerModifiersNode->getAttribute("winner")->getIntValue(); + aiEnabled = playerModifiersNode->getAttribute("aiEnabled")->getIntValue(); + consumeEnabled = playerModifiersNode->getAttribute("consumeEnabled")->getIntValue(); +} + +CellTriggerEvent::CellTriggerEvent() { + type = ctet_Unit; + sourceId = 0; + destId = 0; + //Vec2i destPos; + + triggerCount = 0; +} + +void CellTriggerEvent::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *cellTriggerEventNode = rootNode->addChild("CellTriggerEvent"); + +// CellTriggerEventType type; + cellTriggerEventNode->addAttribute("type",intToStr(type), mapTagReplacements); +// int sourceId; + cellTriggerEventNode->addAttribute("sourceId",intToStr(sourceId), mapTagReplacements); +// int destId; + cellTriggerEventNode->addAttribute("destId",intToStr(destId), mapTagReplacements); +// Vec2i destPos; + cellTriggerEventNode->addAttribute("destPos",destPos.getString(), mapTagReplacements); +// int triggerCount; + cellTriggerEventNode->addAttribute("triggerCount",intToStr(triggerCount), mapTagReplacements); +} + +void CellTriggerEvent::loadGame(const XmlNode *rootNode) { + const XmlNode *cellTriggerEventNode = rootNode->getChild("CellTriggerEvent"); + + type = static_cast(cellTriggerEventNode->getAttribute("type")->getIntValue()); + sourceId = cellTriggerEventNode->getAttribute("sourceId")->getIntValue(); + destId = cellTriggerEventNode->getAttribute("destId")->getIntValue(); + destPos = Vec2i::strToVec2(cellTriggerEventNode->getAttribute("destPos")->getValue()); + triggerCount = cellTriggerEventNode->getAttribute("triggerCount")->getIntValue(); +} + +TimerTriggerEvent::TimerTriggerEvent() { + running = false; + startFrame = 0; + endFrame = 0; +} + +void TimerTriggerEvent::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *timerTriggerEventNode = rootNode->addChild("TimerTriggerEvent"); + +// bool running; + timerTriggerEventNode->addAttribute("running",intToStr(running), mapTagReplacements); +// //time_t startTime; +// //time_t endTime; +// int startFrame; + timerTriggerEventNode->addAttribute("startFrame",intToStr(startFrame), mapTagReplacements); +// int endFrame; + timerTriggerEventNode->addAttribute("endFrame",intToStr(endFrame), mapTagReplacements); +} + +void TimerTriggerEvent::loadGame(const XmlNode *rootNode) { + const XmlNode *timerTriggerEventNode = rootNode->getChild("TimerTriggerEvent"); + + running = timerTriggerEventNode->getAttribute("running")->getIntValue(); + startFrame = timerTriggerEventNode->getAttribute("startFrame")->getIntValue(); + endFrame = timerTriggerEventNode->getAttribute("endFrame")->getIntValue(); +} + // ===================================================== // class ScriptManager // ===================================================== @@ -76,15 +187,18 @@ ScriptManager::ScriptManager() { currentCellTriggeredEventId = 0; currentEventId = 0; inCellTriggerEvent = false; + rootNode = NULL; } ScriptManager::~ScriptManager() { } -void ScriptManager::init(World* world, GameCamera *gameCamera){ +void ScriptManager::init(World* world, GameCamera *gameCamera, const XmlNode *rootNode) { if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //printf("In [%s::%s Line: %d] rootNode [%p][%s]\n",__FILE__,__FUNCTION__,__LINE__,rootNode,(rootNode != NULL ? rootNode->getName().c_str() : "none")); + this->rootNode = rootNode; const Scenario* scenario= world->getScenario(); this->world= world; @@ -93,10 +207,13 @@ void ScriptManager::init(World* world, GameCamera *gameCamera){ //set static instance thisScriptManager= this; + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); currentEventId = 1; CellTriggerEventList.clear(); TimerTriggerEventList.clear(); + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //register functions luaScript.registerFunction(showMessage, "showMessage"); luaScript.registerFunction(setDisplayText, "setDisplayText"); @@ -212,22 +329,28 @@ void ScriptManager::init(World* world, GameCamera *gameCamera){ if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); //call startup function - luaScript.beginCall("startup"); - luaScript.endCall(); + if(this->rootNode == NULL) { + luaScript.beginCall("startup"); + luaScript.endCall(); + } + else { + loadGame(this->rootNode); + this->rootNode = NULL; + } if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } // ========================== events =============================================== -void ScriptManager::onMessageBoxOk(){ +void ScriptManager::onMessageBoxOk() { if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); Lang &lang= Lang::getInstance(); - if(!messageQueue.empty()){ - messageQueue.pop(); - if(!messageQueue.empty()){ + if(messageQueue.empty() == false) { + messageQueue.pop_front(); + if(messageQueue.empty() == false) { messageBox.setText(wrapString(lang.getScenarioString(messageQueue.front().getText()), messageWrapCount)); messageBox.setHeader(lang.getScenarioString(messageQueue.front().getHeader())); } @@ -237,67 +360,77 @@ void ScriptManager::onMessageBoxOk(){ void ScriptManager::onResourceHarvested(){ if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - luaScript.beginCall("resourceHarvested"); - luaScript.endCall(); + if(this->rootNode == NULL) { + luaScript.beginCall("resourceHarvested"); + luaScript.endCall(); + } } void ScriptManager::onUnitCreated(const Unit* unit){ if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - lastCreatedUnitName= unit->getType()->getName(); - lastCreatedUnitId= unit->getId(); - luaScript.beginCall("unitCreated"); - luaScript.endCall(); - luaScript.beginCall("unitCreatedOfType_"+unit->getType()->getName()); - luaScript.endCall(); + if(this->rootNode == NULL) { + lastCreatedUnitName= unit->getType()->getName(); + lastCreatedUnitId= unit->getId(); + luaScript.beginCall("unitCreated"); + luaScript.endCall(); + luaScript.beginCall("unitCreatedOfType_"+unit->getType()->getName()); + luaScript.endCall(); + } } void ScriptManager::onUnitDied(const Unit* unit){ if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(unit->getLastAttackerUnitId() >= 0) { - Unit *killer = world->findUnitById(unit->getLastAttackerUnitId()); + if(this->rootNode == NULL) { + if(unit->getLastAttackerUnitId() >= 0) { + Unit *killer = world->findUnitById(unit->getLastAttackerUnitId()); - if(killer != NULL) { - lastAttackingUnitName= killer->getType()->getName(); - lastAttackingUnitId= killer->getId(); + if(killer != NULL) { + lastAttackingUnitName= killer->getType()->getName(); + lastAttackingUnitId= killer->getId(); - lastDeadUnitKillerName= killer->getType()->getName(); - lastDeadUnitKillerId= killer->getId(); - } - else { - lastDeadUnitKillerName= ""; - lastDeadUnitKillerId= -1; + lastDeadUnitKillerName= killer->getType()->getName(); + lastDeadUnitKillerId= killer->getId(); + } + else { + lastDeadUnitKillerName= ""; + lastDeadUnitKillerId= -1; + } } + + lastAttackedUnitName= unit->getType()->getName(); + lastAttackedUnitId= unit->getId(); + + lastDeadUnitName= unit->getType()->getName(); + lastDeadUnitId= unit->getId(); + lastDeadUnitCauseOfDeath = unit->getCauseOfDeath(); + + luaScript.beginCall("unitDied"); + luaScript.endCall(); } - - lastAttackedUnitName= unit->getType()->getName(); - lastAttackedUnitId= unit->getId(); - - lastDeadUnitName= unit->getType()->getName(); - lastDeadUnitId= unit->getId(); - lastDeadUnitCauseOfDeath = unit->getCauseOfDeath(); - - luaScript.beginCall("unitDied"); - luaScript.endCall(); } void ScriptManager::onUnitAttacked(const Unit* unit) { if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - lastAttackedUnitName= unit->getType()->getName(); - lastAttackedUnitId= unit->getId(); - luaScript.beginCall("unitAttacked"); - luaScript.endCall(); + if(this->rootNode == NULL) { + lastAttackedUnitName= unit->getType()->getName(); + lastAttackedUnitId= unit->getId(); + luaScript.beginCall("unitAttacked"); + luaScript.endCall(); + } } void ScriptManager::onUnitAttacking(const Unit* unit) { if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - lastAttackingUnitName= unit->getType()->getName(); - lastAttackingUnitId= unit->getId(); - luaScript.beginCall("unitAttacking"); - luaScript.endCall(); + if(this->rootNode == NULL) { + lastAttackingUnitName= unit->getType()->getName(); + lastAttackingUnitId= unit->getId(); + luaScript.beginCall("unitAttacking"); + luaScript.endCall(); + } } void ScriptManager::onGameOver(bool won) { @@ -312,7 +445,9 @@ void ScriptManager::onTimerTriggerEvent() { if(TimerTriggerEventList.size() <= 0) { return; } - + if(this->rootNode != NULL) { + return; + } if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] TimerTriggerEventList.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,TimerTriggerEventList.size()); for(std::map::iterator iterMap = TimerTriggerEventList.begin(); @@ -338,6 +473,9 @@ void ScriptManager::onCellTriggerEvent(Unit *movingUnit) { if(CellTriggerEventList.size() <= 0) { return; } + if(this->rootNode != NULL) { + return; + } if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] movingUnit = %p, CellTriggerEventList.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,movingUnit,CellTriggerEventList.size()); @@ -481,7 +619,7 @@ void ScriptManager::showMessage(const string &text, const string &header){ Lang &lang= Lang::getInstance(); - messageQueue.push(ScriptManagerMessage(text, header)); + messageQueue.push_back(ScriptManagerMessage(text, header)); messageBox.setEnabled(true); messageBox.setText(wrapString(lang.getScenarioString(messageQueue.front().getText()), messageWrapCount)); messageBox.setHeader(lang.getScenarioString(messageQueue.front().getHeader())); @@ -1820,4 +1958,217 @@ int ScriptManager::loadScenario(LuaHandle* luaHandle) { return luaArguments.getReturnCount(); } +void ScriptManager::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *scriptManagerNode = rootNode->addChild("ScriptManager"); + + //lua +// string code; + scriptManagerNode->addAttribute("code",code, mapTagReplacements); +// LuaScript luaScript; +// +// //world +// World *world; +// GameCamera *gameCamera; +// +// //misc +// MessageQueue messageQueue; + for(std::list::iterator it = messageQueue.begin(); it != messageQueue.end(); ++it) { + (*it).saveGame(scriptManagerNode); + } +// GraphicMessageBox messageBox; + scriptManagerNode->addAttribute("messageBox_enabled",intToStr(messageBox.getEnabled()), mapTagReplacements); + scriptManagerNode->addAttribute("messageBox_text",messageBox.getText(), mapTagReplacements); + scriptManagerNode->addAttribute("messageBox_header",messageBox.getHeader(), mapTagReplacements); + +// string displayText; + scriptManagerNode->addAttribute("displayText",displayText, mapTagReplacements); +// +// //last created unit +// string lastCreatedUnitName; + scriptManagerNode->addAttribute("lastCreatedUnitName",lastCreatedUnitName, mapTagReplacements); +// int lastCreatedUnitId; + scriptManagerNode->addAttribute("lastCreatedUnitId",intToStr(lastCreatedUnitId), mapTagReplacements); +// +// //last dead unit +// string lastDeadUnitName; + scriptManagerNode->addAttribute("lastDeadUnitName",lastDeadUnitName, mapTagReplacements); +// int lastDeadUnitId; + scriptManagerNode->addAttribute("lastDeadUnitId",intToStr(lastDeadUnitId), mapTagReplacements); +// int lastDeadUnitCauseOfDeath; + scriptManagerNode->addAttribute("lastDeadUnitCauseOfDeath",intToStr(lastDeadUnitCauseOfDeath), mapTagReplacements); +// +// //last dead unit's killer +// string lastDeadUnitKillerName; + scriptManagerNode->addAttribute("lastDeadUnitKillerName",lastDeadUnitKillerName, mapTagReplacements); +// int lastDeadUnitKillerId; + scriptManagerNode->addAttribute("lastDeadUnitKillerId",intToStr(lastDeadUnitKillerId), mapTagReplacements); +// +// //last attacked unit +// string lastAttackedUnitName; + scriptManagerNode->addAttribute("lastAttackedUnitName",lastAttackedUnitName, mapTagReplacements); +// int lastAttackedUnitId; + scriptManagerNode->addAttribute("lastAttackedUnitId",intToStr(lastAttackedUnitId), mapTagReplacements); +// +// //last attacking unit +// string lastAttackingUnitName; + scriptManagerNode->addAttribute("lastAttackingUnitName",lastAttackingUnitName, mapTagReplacements); +// int lastAttackingUnitId; + scriptManagerNode->addAttribute("lastAttackingUnitId",intToStr(lastAttackingUnitId), mapTagReplacements); +// +// // end game state +// bool gameOver; + scriptManagerNode->addAttribute("gameOver",intToStr(gameOver), mapTagReplacements); +// bool gameWon; + scriptManagerNode->addAttribute("gameWon",intToStr(gameWon), mapTagReplacements); +// PlayerModifiers playerModifiers[GameConstants::maxPlayers]; + for(unsigned int i = 0; i < GameConstants::maxPlayers; ++i) { + PlayerModifiers &player = playerModifiers[i]; + player.saveGame(scriptManagerNode); + } +// int currentTimerTriggeredEventId; + scriptManagerNode->addAttribute("currentTimerTriggeredEventId",intToStr(currentTimerTriggeredEventId), mapTagReplacements); +// int currentCellTriggeredEventId; + scriptManagerNode->addAttribute("currentCellTriggeredEventId",intToStr(currentCellTriggeredEventId), mapTagReplacements); +// int currentEventId; + scriptManagerNode->addAttribute("currentEventId",intToStr(currentEventId), mapTagReplacements); +// std::map CellTriggerEventList; + for(std::map::iterator iterMap = CellTriggerEventList.begin(); + iterMap != CellTriggerEventList.end(); ++iterMap) { + XmlNode *cellTriggerEventListNode = scriptManagerNode->addChild("CellTriggerEventList"); + + cellTriggerEventListNode->addAttribute("key",intToStr(iterMap->first), mapTagReplacements); + iterMap->second.saveGame(cellTriggerEventListNode); + } +// std::map TimerTriggerEventList; + for(std::map::iterator iterMap = TimerTriggerEventList.begin(); + iterMap != TimerTriggerEventList.end(); ++iterMap) { + XmlNode *timerTriggerEventListNode = scriptManagerNode->addChild("TimerTriggerEventList"); + + timerTriggerEventListNode->addAttribute("key",intToStr(iterMap->first), mapTagReplacements); + iterMap->second.saveGame(timerTriggerEventListNode); + } + +// bool inCellTriggerEvent; + scriptManagerNode->addAttribute("inCellTriggerEvent",intToStr(inCellTriggerEvent), mapTagReplacements); +// std::vector unRegisterCellTriggerEventList; + for(unsigned int i = 0; i < unRegisterCellTriggerEventList.size(); ++i) { + XmlNode *unRegisterCellTriggerEventListNode = scriptManagerNode->addChild("unRegisterCellTriggerEventList"); + unRegisterCellTriggerEventListNode->addAttribute("eventId",intToStr(unRegisterCellTriggerEventList[i]), mapTagReplacements); + } + + luaScript.saveGame(scriptManagerNode); +} + +void ScriptManager::loadGame(const XmlNode *rootNode) { + const XmlNode *scriptManagerNode = rootNode->getChild("ScriptManager"); + +// string code; + code = scriptManagerNode->getAttribute("code")->getValue(); +// LuaScript luaScript; +// +// //world +// World *world; +// GameCamera *gameCamera; +// +// //misc +// MessageQueue messageQueue; + messageQueue.clear(); + vector messageQueueNodeList = scriptManagerNode->getChildList("ScriptManagerMessage"); + for(unsigned int i = 0; i < messageQueueNodeList.size(); ++i) { + XmlNode *node = messageQueueNodeList[i]; + ScriptManagerMessage msg; + msg.loadGame(node); + messageQueue.push_back(msg); + } + +// GraphicMessageBox messageBox; + messageBox.setEnabled(scriptManagerNode->getAttribute("messageBox_enabled")->getIntValue()); + messageBox.setText(wrapString(scriptManagerNode->getAttribute("messageBox_text")->getValue(),messageWrapCount)); + messageBox.setHeader(scriptManagerNode->getAttribute("messageBox_header")->getValue()); + +// string displayText; + displayText = scriptManagerNode->getAttribute("displayText")->getValue(); +// +// //last created unit +// string lastCreatedUnitName; + lastCreatedUnitName = scriptManagerNode->getAttribute("lastCreatedUnitName")->getValue(); +// int lastCreatedUnitId; + lastCreatedUnitId = scriptManagerNode->getAttribute("lastCreatedUnitId")->getIntValue(); +// +// //last dead unit +// string lastDeadUnitName; + lastDeadUnitName = scriptManagerNode->getAttribute("lastDeadUnitName")->getValue(); +// int lastDeadUnitId; + lastDeadUnitId = scriptManagerNode->getAttribute("lastDeadUnitId")->getIntValue(); +// int lastDeadUnitCauseOfDeath; + lastDeadUnitCauseOfDeath = scriptManagerNode->getAttribute("lastDeadUnitCauseOfDeath")->getIntValue(); +// +// //last dead unit's killer +// string lastDeadUnitKillerName; + lastDeadUnitKillerName = scriptManagerNode->getAttribute("lastDeadUnitKillerName")->getValue(); +// int lastDeadUnitKillerId; + lastDeadUnitKillerId = scriptManagerNode->getAttribute("lastDeadUnitKillerId")->getIntValue(); +// +// //last attacked unit +// string lastAttackedUnitName; + lastAttackedUnitName = scriptManagerNode->getAttribute("lastAttackedUnitName")->getValue(); +// int lastAttackedUnitId; + lastAttackedUnitId = scriptManagerNode->getAttribute("lastAttackedUnitId")->getIntValue(); +// +// //last attacking unit +// string lastAttackingUnitName; + lastAttackingUnitName = scriptManagerNode->getAttribute("lastAttackingUnitName")->getValue(); +// int lastAttackingUnitId; + lastAttackingUnitId = scriptManagerNode->getAttribute("lastAttackingUnitId")->getIntValue(); +// +// // end game state +// bool gameOver; + gameOver = scriptManagerNode->getAttribute("gameOver")->getIntValue(); +// bool gameWon; + gameWon = scriptManagerNode->getAttribute("gameWon")->getIntValue(); +// PlayerModifiers playerModifiers[GameConstants::maxPlayers]; + vector playerModifiersNodeList = scriptManagerNode->getChildList("PlayerModifiers"); + for(unsigned int i = 0; i < playerModifiersNodeList.size(); ++i) { + XmlNode *node = playerModifiersNodeList[i]; + playerModifiers[i].loadGame(node); + } +// int currentTimerTriggeredEventId; + currentTimerTriggeredEventId = scriptManagerNode->getAttribute("currentTimerTriggeredEventId")->getIntValue(); +// int currentCellTriggeredEventId; + currentCellTriggeredEventId = scriptManagerNode->getAttribute("currentCellTriggeredEventId")->getIntValue(); +// int currentEventId; + currentEventId = scriptManagerNode->getAttribute("currentEventId")->getIntValue(); +// std::map CellTriggerEventList; + vector cellTriggerEventListNodeList = scriptManagerNode->getChildList("CellTriggerEventList"); + for(unsigned int i = 0; i < cellTriggerEventListNodeList.size(); ++i) { + XmlNode *node = cellTriggerEventListNodeList[i]; + CellTriggerEvent event; + event.loadGame(node); + CellTriggerEventList[node->getAttribute("key")->getIntValue()] = event; + } + +// std::map TimerTriggerEventList; + vector timerTriggerEventListNodeList = scriptManagerNode->getChildList("TimerTriggerEventList"); + for(unsigned int i = 0; i < timerTriggerEventListNodeList.size(); ++i) { + XmlNode *node = timerTriggerEventListNodeList[i]; + + TimerTriggerEvent event; + event.loadGame(node); + TimerTriggerEventList[node->getAttribute("key")->getIntValue()] = event; + } + +// bool inCellTriggerEvent; + inCellTriggerEvent = scriptManagerNode->getAttribute("inCellTriggerEvent")->getIntValue(); +// std::vector unRegisterCellTriggerEventList; + vector unRegisterCellTriggerEventListNodeList = scriptManagerNode->getChildList("unRegisterCellTriggerEventList"); + for(unsigned int i = 0; i < unRegisterCellTriggerEventListNodeList.size(); ++i) { + XmlNode *node = unRegisterCellTriggerEventListNodeList[i]; + unRegisterCellTriggerEventList.push_back(node->getAttribute("eventId")->getIntValue()); + } + + luaScript.loadGame(scriptManagerNode); +} + + }}//end namespace diff --git a/source/glest_game/game/script_manager.h b/source/glest_game/game/script_manager.h index 9ba974dfb..d21d810d9 100644 --- a/source/glest_game/game/script_manager.h +++ b/source/glest_game/game/script_manager.h @@ -13,19 +13,23 @@ #define _GLEST_GAME_SCRIPT_MANAGER_H_ #include -#include +//#include +#include #include "lua_script.h" #include "components.h" #include "game_constants.h" #include +#include "xml_parser.h" #include "leak_dumper.h" using std::string; -using std::queue; +//using std::queue; +using std::list; using Shared::Graphics::Vec2i; using Shared::Lua::LuaScript; using Shared::Lua::LuaHandle; +using Shared::Xml::XmlNode; namespace Glest{ namespace Game{ @@ -37,15 +41,19 @@ class GameCamera; // class ScriptManagerMessage // ===================================================== -class ScriptManagerMessage{ +class ScriptManagerMessage { private: string text; string header; public: - ScriptManagerMessage(string text, string header) {this->text= text, this->header= header;} + ScriptManagerMessage(); + ScriptManagerMessage(string text, string header); const string &getText() const {return text;} const string &getHeader() const {return header;} + + void saveGame(XmlNode *rootNode); + void loadGame(const XmlNode *rootNode); }; class PlayerModifiers{ @@ -65,7 +73,11 @@ public: bool getAiEnabled() const {return aiEnabled;} bool getConsumeEnabled() const {return consumeEnabled;} + void saveGame(XmlNode *rootNode); + void loadGame(const XmlNode *rootNode); + private: + bool winner; bool aiEnabled; bool consumeEnabled; @@ -84,27 +96,34 @@ enum CellTriggerEventType { class CellTriggerEvent { public: + CellTriggerEvent(); CellTriggerEventType type; int sourceId; int destId; Vec2i destPos; int triggerCount; + + void saveGame(XmlNode *rootNode); + void loadGame(const XmlNode *rootNode); }; class TimerTriggerEvent { public: + TimerTriggerEvent(); bool running; //time_t startTime; //time_t endTime; int startFrame; int endFrame; + void saveGame(XmlNode *rootNode); + void loadGame(const XmlNode *rootNode); }; class ScriptManager { private: - typedef queue MessageQueue; + typedef list MessageQueue; private: @@ -155,6 +174,8 @@ private: bool inCellTriggerEvent; std::vector unRegisterCellTriggerEventList; + const XmlNode *rootNode; + private: static ScriptManager* thisScriptManager; @@ -166,7 +187,7 @@ public: ScriptManager(); ~ScriptManager(); - void init(World* world, GameCamera *gameCamera); + void init(World* world, GameCamera *gameCamera,const XmlNode *rootNode); //message box functions bool getMessageBoxEnabled() const {return !messageQueue.empty();} @@ -187,6 +208,9 @@ public: void onCellTriggerEvent(Unit *movingUnit); void onTimerTriggerEvent(); + void saveGame(XmlNode *rootNode); + void loadGame(const XmlNode *rootNode); + private: string wrapString(const string &str, int wrapCount); diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index c2831b678..0fb99c10c 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -329,7 +329,7 @@ Checksum World::loadMap(const string &path, Checksum *checksum) { } //load map -Checksum World::loadScenario(const string &path, Checksum *checksum, bool resetCurrentScenario) { +Checksum World::loadScenario(const string &path, Checksum *checksum, bool resetCurrentScenario, const XmlNode *rootNode) { //printf("[%s:%s] Line: %d path [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str()); Checksum scenarioChecksum; @@ -340,7 +340,7 @@ Checksum World::loadScenario(const string &path, Checksum *checksum, bool resetC if(resetCurrentScenario == true) { scenario = Scenario(); - scriptManager->init(this, this->getGame()->getGameCameraPtr()); + scriptManager->init(this, this->getGame()->getGameCameraPtr(),rootNode); } scenarioChecksum = scenario.load(path); diff --git a/source/glest_game/world/world.h b/source/glest_game/world/world.h index f91c8a33f..c1ca7602f 100644 --- a/source/glest_game/world/world.h +++ b/source/glest_game/world/world.h @@ -199,7 +199,7 @@ public: Checksum loadTech(const vector pathList, const string &techName, set &factions, Checksum* checksum,std::map > > &loadedFileList); Checksum loadMap(const string &path, Checksum* checksum); - Checksum loadScenario(const string &path, Checksum* checksum,bool resetCurrentScenario=false); + Checksum loadScenario(const string &path, Checksum* checksum,bool resetCurrentScenario=false,const XmlNode *rootNode=NULL); void setQueuedScenario(string scenarioName,bool keepFactions); string getQueuedScenario() const { return queuedScenarioName; } bool getQueuedScenarioKeepFactions() const { return queuedScenarioKeepFactions; } diff --git a/source/shared_lib/include/lua/lua_script.h b/source/shared_lib/include/lua/lua_script.h index 8193db941..b47719457 100644 --- a/source/shared_lib/include/lua/lua_script.h +++ b/source/shared_lib/include/lua/lua_script.h @@ -15,11 +15,13 @@ #include #include #include +#include "xml_parser.h" #include "leak_dumper.h" using std::string; using Shared::Graphics::Vec2i; +using Shared::Xml::XmlNode; namespace Shared{ namespace Lua{ @@ -50,6 +52,9 @@ public: void registerFunction(LuaFunction luaFunction, const string &functionName); + void saveGame(XmlNode *rootNode); + void loadGame(const XmlNode *rootNode); + private: string errorToString(int errorCode); }; diff --git a/source/shared_lib/sources/lua/lua_script.cpp b/source/shared_lib/sources/lua/lua_script.cpp index 60b7de149..6e004647f 100644 --- a/source/shared_lib/sources/lua/lua_script.cpp +++ b/source/shared_lib/sources/lua/lua_script.cpp @@ -140,6 +140,117 @@ void LuaScript::DumpGlobals() } } +void LuaScript::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + + LuaHandle *L = luaState; + // push the first key (nil = beginning of table) + lua_pushnil(L); + + // lua_next will: + // 1 - pop the key + // 2 - push the next key + // 3 - push the value at that key + // ... so the key will be at index -2 and the value at index -1 + while (lua_next(L, LUA_GLOBALSINDEX) != 0) { + // get type of key and value + int key_type = lua_type(L, -2); + int value_type = lua_type(L, -1); + + // support only string keys + // globals aren't likely to have a non-string key, but just to be certain ... + if (key_type != LUA_TSTRING) { + lua_pop(L, 1); // pop the value so that the top contains the key for the next iteration + continue; + } + + // support only number, boolean and string values + if (value_type != LUA_TNUMBER && + value_type != LUA_TBOOLEAN && + value_type != LUA_TSTRING) { + lua_pop(L, 1); // again, pop the value before going to the next loop iteration + continue; + } + + // get the key as a string + string key_string = lua_tostring(L, -2); // no copy required - we already know this is a string + + // do not support variables that start with '_' + // lua has some predefined values like _VERSION. They all start with underscore + + if (!key_string.size()) { // this again is highly unlikely, but still ... + lua_pop(L, 1); + continue; + } + if (key_string[0] == '_') { + lua_pop(L, 1); + continue; + } + + string value_string; + + // convert the value to a string. This depends on its type + switch (value_type) { + case LUA_TSTRING: + case LUA_TNUMBER: + // numbers can be converted to strings + + // get the value as a string (this requires a copy because traversing tables + // uses the top of the stack as an index. If conversion from a number to string + // happens, the top of the stack will be altered and the table index will become invalid) + lua_pushvalue(L, -1); + value_string = lua_tostring(L, -1); + lua_pop(L, 1); + break; + case LUA_TBOOLEAN: + value_string = lua_toboolean(L, -1) == 0 ? "false" : "true"; + break; + } + + // enclose the value in "" if it is a string + if (value_type == LUA_TSTRING) { + value_string = "\"" + value_string + "\""; + } + + // resulting line. Somehow save this and when you need to restore it, just + // call luaL_dostring with that line. + //SaveLine(key_string + " = " + value_string); // Pop the value so the index remains on top of the stack for the next iteration + //printf("Found global LUA var: %s = %s\n",key_string.c_str(),value_string.c_str()); + XmlNode *luaScriptNode = rootNode->addChild("LuaScript"); + luaScriptNode->addAttribute("variable",key_string, mapTagReplacements); + luaScriptNode->addAttribute("value",value_string, mapTagReplacements); + luaScriptNode->addAttribute("value_type",intToStr(value_type), mapTagReplacements); + + lua_pop(L, 1); + } +} + +void LuaScript::loadGame(const XmlNode *rootNode) { + const XmlNode *luaScriptNode = rootNode; + + vector luaScriptNodeList = rootNode->getChildList("LuaScript"); + for(unsigned int i = 0; i < luaScriptNodeList.size(); ++i) { + XmlNode *node = luaScriptNodeList[i]; + + string variable = node->getAttribute("variable")->getValue(); + int value_type = node->getAttribute("value_type")->getIntValue(); + + switch (value_type) { + case LUA_TSTRING: + lua_pushstring( luaState, node->getAttribute("value")->getValue().c_str() ); + break; + case LUA_TNUMBER: + lua_pushnumber( luaState, node->getAttribute("value")->getIntValue() ); + break; + case LUA_TBOOLEAN: + lua_pushboolean( luaState, node->getAttribute("value")->getIntValue() ); + break; + } + + lua_setglobal( luaState, variable.c_str() ); + } +} + LuaScript::~LuaScript() { Lua_STREFLOP_Wrapper streflopWrapper;