diff --git a/src/app/app.cpp b/src/app/app.cpp index 6f333895..fb2656c4 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -1799,8 +1799,8 @@ void CApplication::SetLanguage(Language language) putenv(S_LANGUAGE); GetLogger()->Trace("SetLanguage: Set LANGUAGE=%s in environment\n", locale.c_str()); } - - setlocale(LC_ALL, ""); + + std::locale::global(std::locale(std::locale(""), "C", std::locale::numeric)); bindtextdomain("colobot", m_langPath.c_str()); bind_textdomain_codeset("colobot", "UTF-8"); diff --git a/src/common/resources/resourcemanager.cpp b/src/common/resources/resourcemanager.cpp index d2d69f54..73298710 100644 --- a/src/common/resources/resourcemanager.cpp +++ b/src/common/resources/resourcemanager.cpp @@ -167,7 +167,7 @@ bool CResourceManager::CreateDirectory(const std::string& directory) return PHYSFS_mkdir(CleanPath(directory).c_str()); } -//TODO: Don't use boost filesystem here +//TODO: Don't use boost::filesystem here bool CResourceManager::RemoveDirectory(const std::string& directory) { bool success = true; @@ -219,6 +219,28 @@ std::vector CResourceManager::ListDirectories(const std::string &di return result; } +long long CResourceManager::GetFileSize(const std::string& filename) +{ + if(PHYSFS_isInit()) + { + PHYSFS_File* file = PHYSFS_openRead(CleanPath(filename).c_str()); + if(file == nullptr) return -1; + long long size = PHYSFS_fileLength(file); + PHYSFS_close(file); + return size; + } + return -1; +} + +long long CResourceManager::GetLastModificationTime(const std::string& filename) +{ + if(PHYSFS_isInit()) + { + return PHYSFS_getLastModTime(CleanPath(filename).c_str()); + } + return -1; +} + int CResourceManager::SDLClose(SDL_RWops *context) { diff --git a/src/common/resources/resourcemanager.h b/src/common/resources/resourcemanager.h index 4d79e9b6..e34ea103 100644 --- a/src/common/resources/resourcemanager.h +++ b/src/common/resources/resourcemanager.h @@ -56,6 +56,12 @@ public: static std::vector ListFiles(const std::string &directory); //! List directories contained in directory static std::vector ListDirectories(const std::string &directory); + + + //! Returns file size in bytes + static long long GetFileSize(const std::string &filename); + //! Returns last modification date as timestamp + static long long GetLastModificationTime(const std::string &filename); private: static int SDLSeek(SDL_RWops *context, int offset, int whence); diff --git a/src/object/auto/auto.cpp b/src/object/auto/auto.cpp index fb6698b7..4f12f2ff 100644 --- a/src/object/auto/auto.cpp +++ b/src/object/auto/auto.cpp @@ -26,6 +26,9 @@ #include "common/event.h" #include "common/iman.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" + #include "script/cmdtoken.h" #include "ui/interface.h" @@ -424,37 +427,26 @@ void CAuto::SetMotor(bool bMotor) // Saves all parameters of the controller. -bool CAuto::Write(char *line) +bool CAuto::Write(CLevelParserLine* line) { - char name[100]; - - sprintf(name, " aType=%d", m_type); - strcat(line, name); - - sprintf(name, " aBusy=%d", m_bBusy); - strcat(line, name); - - sprintf(name, " aTime=%.2f", m_time); - strcat(line, name); - - sprintf(name, " aProgressTime=%.2f", m_progressTime); - strcat(line, name); - - sprintf(name, " aProgressTotal=%.2f", m_progressTotal); - strcat(line, name); + line->AddParam("aType", new CLevelParserParam(m_type)); + line->AddParam("aBusy", new CLevelParserParam(m_bBusy)); + line->AddParam("aTime", new CLevelParserParam(m_time)); + line->AddParam("aProgressTime", new CLevelParserParam(m_progressTime)); + line->AddParam("aProgressTotal", new CLevelParserParam(m_progressTotal)); return false; } // Return all settings to the controller. -bool CAuto::Read(char *line) +bool CAuto::Read(CLevelParserLine* line) { - m_type = static_cast(OpInt(line, "aType", OBJECT_NULL)); - m_bBusy = OpInt(line, "aBusy", 0); - m_time = OpFloat(line, "aTime", 0.0f); - m_progressTime = OpFloat(line, "aProgressTime", 0.0f); - m_progressTotal = OpFloat(line, "aProgressTotal", 0.0f); + m_type = line->GetParam("aType")->AsObjectType(); + m_bBusy = line->GetParam("aBusy")->AsBool(); + m_time = line->GetParam("aTime")->AsFloat(); + m_progressTime = line->GetParam("aProgressTime")->AsFloat(); + m_progressTotal = line->GetParam("aProgressTotal")->AsFloat(); return false; } diff --git a/src/object/auto/auto.h b/src/object/auto/auto.h index af7766cc..7053aa2b 100644 --- a/src/object/auto/auto.h +++ b/src/object/auto/auto.h @@ -29,6 +29,7 @@ class CInstanceManager; class CRobotMain; class CSoundInterface; +class CLevelParserLine; namespace Ui { class CInterface; @@ -80,8 +81,8 @@ public: virtual bool GetMotor(); virtual void SetMotor(bool bMotor); - virtual bool Write(char *line); - virtual bool Read(char *line); + virtual bool Write(CLevelParserLine* line); + virtual bool Read(CLevelParserLine* line); protected: void CheckInterface(Ui::CWindow *pw, EventType event, bool bState); diff --git a/src/object/auto/autoconvert.cpp b/src/object/auto/autoconvert.cpp index 5dc80e94..23e41a1c 100644 --- a/src/object/auto/autoconvert.cpp +++ b/src/object/auto/autoconvert.cpp @@ -24,6 +24,9 @@ #include "math/geometry.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" + #include "script/cmdtoken.h" #include "ui/interface.h" @@ -361,41 +364,30 @@ bool CAutoConvert::CreateInterface(bool bSelect) // Saves all parameters of the controller. -bool CAutoConvert::Write(char *line) +bool CAutoConvert::Write(CLevelParserLine* line) { - char name[100]; - if ( m_phase == ACP_STOP || m_phase == ACP_WAIT ) return false; - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); return true; } // Restores all parameters of the controller. -bool CAutoConvert::Read(char *line) +bool CAutoConvert::Read(CLevelParserLine* line) { - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoConvertPhase >(OpInt(line, "aPhase", ACP_WAIT)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); + m_phase = static_cast< AutoConvertPhase >(line->GetParam("aPhase")->AsInt(ACP_WAIT)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); m_lastParticle = 0.0f; diff --git a/src/object/auto/autoconvert.h b/src/object/auto/autoconvert.h index 54cdb986..4fab9b0e 100644 --- a/src/object/auto/autoconvert.h +++ b/src/object/auto/autoconvert.h @@ -52,8 +52,8 @@ public: bool CreateInterface(bool bSelect); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: CObject* SearchStone(ObjectType type); diff --git a/src/object/auto/autoderrick.cpp b/src/object/auto/autoderrick.cpp index f797ed97..c8e93769 100644 --- a/src/object/auto/autoderrick.cpp +++ b/src/object/auto/autoderrick.cpp @@ -26,6 +26,9 @@ #include "math/geometry.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" + #include "script/cmdtoken.h" #include "ui/interface.h" @@ -428,40 +431,29 @@ bool CAutoDerrick::CreateInterface(bool bSelect) // Saves all parameters of the controller. -bool CAutoDerrick::Write(char *line) +bool CAutoDerrick::Write(CLevelParserLine* line) { - char name[100]; - if ( m_phase == ADP_WAIT ) return false; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); return true; } // Restores all parameters of the controller. -bool CAutoDerrick::Read(char *line) +bool CAutoDerrick::Read(CLevelParserLine* line) { - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoDerrickPhase >(OpInt(line, "aPhase", ADP_WAIT)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); + m_phase = static_cast< AutoDerrickPhase >(line->GetParam("aPhase")->AsInt(ADP_WAIT)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); m_lastParticle = 0.0f; diff --git a/src/object/auto/autoderrick.h b/src/object/auto/autoderrick.h index dd2f4d98..36825083 100644 --- a/src/object/auto/autoderrick.h +++ b/src/object/auto/autoderrick.h @@ -51,8 +51,8 @@ public: bool CreateInterface(bool bSelect); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: CObject* SearchFret(); diff --git a/src/object/auto/autodestroyer.cpp b/src/object/auto/autodestroyer.cpp index bc392f55..fa5c130f 100644 --- a/src/object/auto/autodestroyer.cpp +++ b/src/object/auto/autodestroyer.cpp @@ -22,6 +22,9 @@ #include "common/iman.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" + #include "script/cmdtoken.h" #include "ui/interface.h" @@ -357,40 +360,29 @@ Error CAutoDestroyer::GetError() // Saves all parameters of the controller. -bool CAutoDestroyer::Write(char *line) +bool CAutoDestroyer::Write(CLevelParserLine* line) { - char name[100]; - if ( m_phase == ADEP_WAIT ) return false; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); return true; } // Restores all parameters of the controller. -bool CAutoDestroyer::Read(char *line) +bool CAutoDestroyer::Read(CLevelParserLine* line) { - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoDestroyerPhase >(OpInt(line, "aPhase", ADEP_WAIT)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); + m_phase = static_cast< AutoDestroyerPhase >(line->GetParam("aPhase")->AsInt(ADEP_WAIT)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); m_lastParticle = 0.0f; diff --git a/src/object/auto/autodestroyer.h b/src/object/auto/autodestroyer.h index 14949e26..5b3b86a2 100644 --- a/src/object/auto/autodestroyer.h +++ b/src/object/auto/autodestroyer.h @@ -52,8 +52,8 @@ public: bool CreateInterface(bool bSelect); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: CObject* SearchPlastic(); diff --git a/src/object/auto/autoegg.cpp b/src/object/auto/autoegg.cpp index 828821a0..2a2af34f 100644 --- a/src/object/auto/autoegg.cpp +++ b/src/object/auto/autoegg.cpp @@ -24,6 +24,9 @@ #include "math/geometry.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" + #include "script/cmdtoken.h" #include @@ -310,52 +313,35 @@ CObject* CAutoEgg::SearchAlien() // Saves all parameters of the controller. -bool CAutoEgg::Write(char *line) +bool CAutoEgg::Write(CLevelParserLine* line) { - char name[100]; - if ( m_phase == AEP_NULL ) return false; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.5f", m_speed); - strcat(line, name); - - sprintf(name, " aParamType=%s", GetTypeObject(m_type)); - strcat(line, name); - - sprintf(name, " aParamValue1=%.2f", m_value); - strcat(line, name); - - sprintf(name, " aParamString=\"%s\"", m_string); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); + line->AddParam("aParamType", new CLevelParserParam(m_type)); + line->AddParam("aParamValue1", new CLevelParserParam(m_value)); + line->AddParam("aParamString", new CLevelParserParam(m_string)); return true; } // Restores all parameters of the controller. -bool CAutoEgg::Read(char *line) +bool CAutoEgg::Read(CLevelParserLine* line) { - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoEggPhase >(OpInt(line, "aPhase", AEP_NULL)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - m_type = OpTypeObject(line, "aParamType", OBJECT_NULL); - m_value = OpFloat(line, "aParamValue1", 0.0f); - OpString(line, "aParamString", m_string); + m_phase = static_cast< AutoEggPhase >(line->GetParam("aPhase")->AsInt(AEP_NULL)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); + m_type = line->GetParam("aParamType")->AsObjectType(OBJECT_NULL); + m_value = line->GetParam("aParamValue1")->AsFloat(0.0f); + strcpy(m_string, line->GetParam("aParamString")->AsString("").c_str()); return true; } diff --git a/src/object/auto/autoegg.h b/src/object/auto/autoegg.h index 54c6e34c..e28eef1d 100644 --- a/src/object/auto/autoegg.h +++ b/src/object/auto/autoegg.h @@ -54,8 +54,8 @@ public: bool SetValue(int rank, float value); bool SetString(char *string); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: CObject* SearchAlien(); diff --git a/src/object/auto/autoenergy.cpp b/src/object/auto/autoenergy.cpp index ea97cc80..b2371f1e 100644 --- a/src/object/auto/autoenergy.cpp +++ b/src/object/auto/autoenergy.cpp @@ -26,6 +26,9 @@ #include "math/geometry.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" + #include "script/cmdtoken.h" #include "ui/interface.h" @@ -609,41 +612,30 @@ void CAutoEnergy::UpdateInterface(float rTime) // Saves all parameters of the controller. -bool CAutoEnergy::Write(char *line) +bool CAutoEnergy::Write(CLevelParserLine* line) { - char name[100]; - if ( m_phase == AENP_STOP || m_phase == AENP_WAIT ) return false; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); return true; } // Restores all parameters of the controller. -bool CAutoEnergy::Read(char *line) +bool CAutoEnergy::Read(CLevelParserLine* line) { - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoEnergyPhase >(OpInt(line, "aPhase", AENP_WAIT)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); + m_phase = static_cast< AutoEnergyPhase >(line->GetParam("aPhase")->AsInt(AENP_WAIT)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); m_lastUpdateTime = 0.0f; m_lastParticle = 0.0f; diff --git a/src/object/auto/autoenergy.h b/src/object/auto/autoenergy.h index fc6f470b..ec3cce12 100644 --- a/src/object/auto/autoenergy.h +++ b/src/object/auto/autoenergy.h @@ -51,8 +51,8 @@ public: bool CreateInterface(bool bSelect); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: void UpdateInterface(float rTime); diff --git a/src/object/auto/autofactory.cpp b/src/object/auto/autofactory.cpp index 825ea53f..dc6bab1a 100644 --- a/src/object/auto/autofactory.cpp +++ b/src/object/auto/autofactory.cpp @@ -27,6 +27,8 @@ #include "object/robotmain.h" #include "object/brain.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" #include "physics/physics.h" @@ -515,40 +517,29 @@ bool CAutoFactory::EventProcess(const Event &event) // Saves all parameters of the controller. -bool CAutoFactory::Write(char *line) +bool CAutoFactory::Write(CLevelParserLine* line) { - char name[100]; - if ( m_phase == AFP_WAIT ) return false; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); return true; } // Restores all parameters of the controller -bool CAutoFactory::Read(char *line) +bool CAutoFactory::Read(CLevelParserLine* line) { - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoFactoryPhase >(OpInt(line, "aPhase", AFP_WAIT)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); + m_phase = static_cast< AutoFactoryPhase >(line->GetParam("aPhase")->AsInt(AFP_WAIT)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); m_lastParticle = 0.0f; m_fretPos = m_object->GetPosition(0); diff --git a/src/object/auto/autofactory.h b/src/object/auto/autofactory.h index 60a44fba..65186ff0 100644 --- a/src/object/auto/autofactory.h +++ b/src/object/auto/autofactory.h @@ -55,8 +55,8 @@ public: bool CreateInterface(bool bSelect); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: void UpdateInterface(); diff --git a/src/object/auto/autoinfo.cpp b/src/object/auto/autoinfo.cpp index 7b8622f9..e1da37a8 100644 --- a/src/object/auto/autoinfo.cpp +++ b/src/object/auto/autoinfo.cpp @@ -20,7 +20,12 @@ #include "object/auto/autoinfo.h" + +#include "object/level/parserline.h" +#include "object/level/parserparam.h" + #include "script/cmdtoken.h" + #include "ui/interface.h" #include "ui/list.h" #include "ui/window.h" @@ -475,40 +480,29 @@ void CAutoInfo::UpdateListVirus() // Saves all parameters of the controller. -bool CAutoInfo::Write(char *line) +bool CAutoInfo::Write(CLevelParserLine* line) { - char name[100]; - if ( m_phase == AIP_WAIT ) return false; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); return true; } // Restores all parameters of the controller. -bool CAutoInfo::Read(char *line) +bool CAutoInfo::Read(CLevelParserLine* line) { - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoInfoPhase > (OpInt(line, "aPhase", AIP_WAIT)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); + m_phase = static_cast< AutoInfoPhase >(line->GetParam("aPhase")->AsInt(AIP_WAIT)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); m_lastParticle = 0.0f; diff --git a/src/object/auto/autoinfo.h b/src/object/auto/autoinfo.h index 632edf8f..ac9f729d 100644 --- a/src/object/auto/autoinfo.h +++ b/src/object/auto/autoinfo.h @@ -51,8 +51,8 @@ public: bool CreateInterface(bool bSelect); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: void UpdateInterface(float rTime); diff --git a/src/object/auto/autolabo.cpp b/src/object/auto/autolabo.cpp index 3a0be92e..f9ae1041 100644 --- a/src/object/auto/autolabo.cpp +++ b/src/object/auto/autolabo.cpp @@ -26,6 +26,8 @@ #include "math/geometry.h" #include "object/robotmain.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" #include "script/cmdtoken.h" @@ -586,47 +588,31 @@ void CAutoLabo::SoundManip(float time, float amplitude, float frequency) // Saves all parameters of the controller. -bool CAutoLabo::Write(char *line) +bool CAutoLabo::Write(CLevelParserLine* line) { - Math::Vector pos; - char name[100]; - if ( m_phase == ALAP_WAIT ) return false; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - sprintf(name, " aResearch=%d", m_research); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); + line->AddParam("aResearch", new CLevelParserParam(static_cast(m_research))); return true; } // Restores all parameters of the controller. -bool CAutoLabo::Read(char *line) +bool CAutoLabo::Read(CLevelParserLine* line) { - Math::Vector pos; - - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoLaboPhase >(OpInt(line, "aPhase", ALAP_WAIT)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - m_research = static_cast< ResearchType >(OpInt(line, "aResearch", 0)); + m_phase = static_cast< AutoLaboPhase >(line->GetParam("aPhase")->AsInt(ALAP_WAIT)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); + m_research = static_cast< ResearchType >(line->GetParam("aResearch")->AsInt(0)); m_lastParticle = 0.0f; diff --git a/src/object/auto/autolabo.h b/src/object/auto/autolabo.h index b62668ee..84d3f677 100644 --- a/src/object/auto/autolabo.h +++ b/src/object/auto/autolabo.h @@ -55,8 +55,8 @@ public: bool CreateInterface(bool bSelect); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: void UpdateInterface(); diff --git a/src/object/auto/automush.cpp b/src/object/auto/automush.cpp index c05878dd..836056c5 100644 --- a/src/object/auto/automush.cpp +++ b/src/object/auto/automush.cpp @@ -22,6 +22,9 @@ #include "common/iman.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" + #include "script/cmdtoken.h" @@ -31,7 +34,7 @@ // Object's constructor. - CAutoMush::CAutoMush(CObject* object) : CAuto(object) +CAutoMush::CAutoMush(CObject* object) : CAuto(object) { Init(); } @@ -301,43 +304,29 @@ Error CAutoMush::GetError() // Saves all parameters of the controller. -bool CAutoMush::Write(char *line) +bool CAutoMush::Write(CLevelParserLine* line) { - Math::Vector pos; - char name[100]; - if ( m_phase == AMP_WAIT ) return false; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); return true; } // Restores all parameters of the controller. -bool CAutoMush::Read(char *line) +bool CAutoMush::Read(CLevelParserLine* line) { - Math::Vector pos; - - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoMushPhase >(OpInt(line, "aPhase", AMP_WAIT)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); + m_phase = static_cast< AutoMushPhase >(line->GetParam("aPhase")->AsInt(AMP_WAIT)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); m_lastParticle = 0.0f; diff --git a/src/object/auto/automush.h b/src/object/auto/automush.h index 2d70eaa0..273dcc40 100644 --- a/src/object/auto/automush.h +++ b/src/object/auto/automush.h @@ -49,8 +49,8 @@ public: bool EventProcess(const Event &event); Error GetError(); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: bool SearchTarget(); diff --git a/src/object/auto/autonest.cpp b/src/object/auto/autonest.cpp index 1c3b834e..94e09f6e 100644 --- a/src/object/auto/autonest.cpp +++ b/src/object/auto/autonest.cpp @@ -24,6 +24,9 @@ #include "graphics/engine/terrain.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" + #include "script/cmdtoken.h" #include @@ -32,7 +35,7 @@ // Object's constructor. - CAutoNest::CAutoNest(CObject* object) : CAuto(object) +CAutoNest::CAutoNest(CObject* object) : CAuto(object) { Init(); } @@ -232,43 +235,29 @@ Error CAutoNest::GetError() // Saves all parameters of the controller. -bool CAutoNest::Write(char *line) +bool CAutoNest::Write(CLevelParserLine* line) { - Math::Vector pos; - char name[100]; - if ( m_phase == ANP_WAIT ) return false; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); return true; } // Restores all parameters of the controller. -bool CAutoNest::Read(char *line) +bool CAutoNest::Read(CLevelParserLine* line) { - Math::Vector pos; - - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoNestPhase >(OpInt(line, "aPhase", ANP_WAIT)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); + m_phase = static_cast< AutoNestPhase >(line->GetParam("aPhase")->AsInt(ANP_WAIT)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); m_lastParticle = 0.0f; diff --git a/src/object/auto/autonest.h b/src/object/auto/autonest.h index df16367c..c3279dfe 100644 --- a/src/object/auto/autonest.h +++ b/src/object/auto/autonest.h @@ -46,8 +46,8 @@ public: bool EventProcess(const Event &event); Error GetError(); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: bool SearchFree(Math::Vector pos); diff --git a/src/object/auto/autonuclear.cpp b/src/object/auto/autonuclear.cpp index 8fc74616..a779bd3b 100644 --- a/src/object/auto/autonuclear.cpp +++ b/src/object/auto/autonuclear.cpp @@ -24,6 +24,9 @@ #include "math/geometry.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" + #include "script/cmdtoken.h" #include "ui/interface.h" @@ -444,41 +447,30 @@ Error CAutoNuclear::GetError() // Saves all parameters of the controller. -bool CAutoNuclear::Write(char *line) +bool CAutoNuclear::Write(CLevelParserLine* line) { - char name[100]; - if ( m_phase == ANUP_STOP || m_phase == ANUP_WAIT ) return false; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); return true; } // Restores all parameters of the controller. -bool CAutoNuclear::Read(char *line) +bool CAutoNuclear::Read(CLevelParserLine* line) { - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoNuclearPhase >(OpInt(line, "aPhase", ANUP_WAIT)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); + m_phase = static_cast< AutoNuclearPhase >(line->GetParam("aPhase")->AsInt(ANUP_WAIT)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); m_lastParticle = 0.0f; diff --git a/src/object/auto/autonuclear.h b/src/object/auto/autonuclear.h index 83d8a912..e21ecc20 100644 --- a/src/object/auto/autonuclear.h +++ b/src/object/auto/autonuclear.h @@ -51,8 +51,8 @@ public: bool CreateInterface(bool bSelect); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: CObject* SearchUranium(); diff --git a/src/object/auto/autopara.cpp b/src/object/auto/autopara.cpp index 4a8e6081..0149f8ba 100644 --- a/src/object/auto/autopara.cpp +++ b/src/object/auto/autopara.cpp @@ -25,6 +25,9 @@ #include "math/geometry.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" + #include "script/cmdtoken.h" #include "ui/interface.h" @@ -289,40 +292,29 @@ void CAutoPara::ChargeObject(float rTime) // Saves all parameters of the controller. -bool CAutoPara::Write(char *line) +bool CAutoPara::Write(CLevelParserLine* line) { - char name[100]; - if ( m_phase == APAP_WAIT ) return false; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); return true; } // Restores all parameters of the controller. -bool CAutoPara::Read(char *line) +bool CAutoPara::Read(CLevelParserLine* line) { - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoParaPhase >(OpInt(line, "aPhase", APAP_WAIT)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); + m_phase = static_cast< AutoParaPhase >(line->GetParam("aPhase")->AsInt(APAP_WAIT)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); m_lastParticle = 0.0f; diff --git a/src/object/auto/autopara.h b/src/object/auto/autopara.h index 059d813f..ec2c9722 100644 --- a/src/object/auto/autopara.h +++ b/src/object/auto/autopara.h @@ -50,8 +50,8 @@ public: bool CreateInterface(bool bSelect); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: void ChargeObject(float rTime); diff --git a/src/object/auto/autorepair.cpp b/src/object/auto/autorepair.cpp index f118ab5d..5a88df2f 100644 --- a/src/object/auto/autorepair.cpp +++ b/src/object/auto/autorepair.cpp @@ -22,6 +22,9 @@ #include "common/iman.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" + #include "physics/physics.h" #include "script/cmdtoken.h" @@ -302,40 +305,29 @@ Error CAutoRepair::GetError() // Saves all parameters of the controller. -bool CAutoRepair::Write(char *line) +bool CAutoRepair::Write(CLevelParserLine* line) { - char name[100]; - if ( m_phase == ARP_WAIT ) return false; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); return true; } // Restores all parameters of the controller. -bool CAutoRepair::Read(char *line) +bool CAutoRepair::Read(CLevelParserLine* line) { - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoRepairPhase >(OpInt(line, "aPhase", ARP_WAIT)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); + m_phase = static_cast< AutoRepairPhase >(line->GetParam("aPhase")->AsInt(ARP_WAIT)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); m_lastParticle = 0.0f; diff --git a/src/object/auto/autorepair.h b/src/object/auto/autorepair.h index e3772795..a82a4797 100644 --- a/src/object/auto/autorepair.h +++ b/src/object/auto/autorepair.h @@ -51,8 +51,8 @@ public: bool CreateInterface(bool bSelect); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: CObject* SearchVehicle(); diff --git a/src/object/auto/autoresearch.cpp b/src/object/auto/autoresearch.cpp index ed6ce9d6..dc9e437b 100644 --- a/src/object/auto/autoresearch.cpp +++ b/src/object/auto/autoresearch.cpp @@ -25,6 +25,8 @@ #include "math/geometry.h" #include "object/robotmain.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" #include "script/cmdtoken.h" @@ -563,44 +565,31 @@ void CAutoResearch::FireStopUpdate(float progress, bool bLightOn) // Saves all parameters of the controller. -bool CAutoResearch::Write(char *line) +bool CAutoResearch::Write(CLevelParserLine* line) { - char name[100]; - if ( m_phase == ALP_WAIT ) return false; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - sprintf(name, " aResearch=%d", m_research); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); + line->AddParam("aResearch", new CLevelParserParam(static_cast(m_research))); return true; } // Restores all parameters of the controller. -bool CAutoResearch::Read(char *line) +bool CAutoResearch::Read(CLevelParserLine* line) { - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoResearchPhase >(OpInt(line, "aPhase", ALP_WAIT)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - m_research = static_cast< ResearchType >(OpInt(line, "aResearch", 0)); + m_phase = static_cast< AutoResearchPhase >(line->GetParam("aPhase")->AsInt(ALP_WAIT)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); + m_research = static_cast< ResearchType >(line->GetParam("aResearch")->AsInt(0)); m_lastUpdateTime = 0.0f; m_lastParticle = 0.0f; diff --git a/src/object/auto/autoresearch.h b/src/object/auto/autoresearch.h index 6b76b3d7..c819d520 100644 --- a/src/object/auto/autoresearch.h +++ b/src/object/auto/autoresearch.h @@ -49,8 +49,8 @@ public: bool CreateInterface(bool bSelect); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: void UpdateInterface(); diff --git a/src/object/auto/autosafe.cpp b/src/object/auto/autosafe.cpp index 7337c1bf..f51243c9 100644 --- a/src/object/auto/autosafe.cpp +++ b/src/object/auto/autosafe.cpp @@ -25,6 +25,8 @@ #include "math/geometry.h" #include "object/robotmain.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" #include "script/cmdtoken.h" @@ -353,40 +355,29 @@ Error CAutoSafe::GetError() // Saves all parameters of the controller. -bool CAutoSafe::Write(char *line) +bool CAutoSafe::Write(CLevelParserLine* line) { - char name[100]; - if ( m_phase == ASAP_WAIT ) return false; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); return true; } // Restores all parameters of the controller. -bool CAutoSafe::Read(char *line) +bool CAutoSafe::Read(CLevelParserLine* line) { - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoSafePhase >(OpInt(line, "aPhase", ASAP_WAIT)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); + m_phase = static_cast< AutoSafePhase >(line->GetParam("aPhase")->AsInt(ASAP_WAIT)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); m_lastParticle = 0.0f; diff --git a/src/object/auto/autosafe.h b/src/object/auto/autosafe.h index 60219dd9..fa8ed834 100644 --- a/src/object/auto/autosafe.h +++ b/src/object/auto/autosafe.h @@ -49,8 +49,8 @@ public: bool CreateInterface(bool bSelect); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: int CountKeys(); diff --git a/src/object/auto/autotower.cpp b/src/object/auto/autotower.cpp index 7e584f95..daf28aa1 100644 --- a/src/object/auto/autotower.cpp +++ b/src/object/auto/autotower.cpp @@ -24,6 +24,9 @@ #include "math/geometry.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" + #include "physics/physics.h" #include "script/cmdtoken.h" @@ -485,60 +488,39 @@ void CAutoTower::UpdateInterface(float rTime) // Saves all parameters of the controller. -bool CAutoTower::Write(char *line) +bool CAutoTower::Write(CLevelParserLine* line) { - char name[100]; - if ( m_phase == ATP_WAIT ) return false; - - sprintf(name, " aExist=%d", 1); - strcat(line, name); - + + line->AddParam("aExist", new CLevelParserParam(true)); CAuto::Write(line); - - sprintf(name, " aPhase=%d", m_phase); - strcat(line, name); - - sprintf(name, " aProgress=%.2f", m_progress); - strcat(line, name); - - sprintf(name, " aSpeed=%.2f", m_speed); - strcat(line, name); - - sprintf(name, " aTargetPos=%.2f;%.2f;%.2f", m_targetPos.x, m_targetPos.y, m_targetPos.z); - strcat(line, name); - - sprintf(name, " aAngleYactual=%.2f", m_angleYactual); - strcat(line, name); - - sprintf(name, " aAngleZactual=%.2f", m_angleZactual); - strcat(line, name); - - sprintf(name, " aAngleYfinal=%.2f", m_angleYfinal); - strcat(line, name); - - sprintf(name, " aAngleZfinal=%.2f", m_angleZfinal); - strcat(line, name); + line->AddParam("aPhase", new CLevelParserParam(static_cast(m_phase))); + line->AddParam("aProgress", new CLevelParserParam(m_progress)); + line->AddParam("aSpeed", new CLevelParserParam(m_speed)); + line->AddParam("aTargetPos", new CLevelParserParam(m_targetPos)); + line->AddParam("aAngleYactual", new CLevelParserParam(m_angleYactual)); + line->AddParam("aAngleZactual", new CLevelParserParam(m_angleZactual)); + line->AddParam("aAngleYfinal", new CLevelParserParam(m_angleYfinal)); + line->AddParam("aAngleZfinal", new CLevelParserParam(m_angleZfinal)); return true; } // Restores all parameters of the controller. -bool CAutoTower::Read(char *line) +bool CAutoTower::Read(CLevelParserLine* line) { - if ( OpInt(line, "aExist", 0) == 0 ) return false; + if ( !line->GetParam("aExist")->AsBool(false) ) return false; CAuto::Read(line); - - m_phase = static_cast< AutoTowerPhase >(OpInt(line, "aPhase", ATP_WAIT)); - m_progress = OpFloat(line, "aProgress", 0.0f); - m_speed = OpFloat(line, "aSpeed", 1.0f); - m_targetPos = OpDir(line, "aTargetPos"); - m_angleYactual = OpFloat(line, "aAngleYactual", 0.0f); - m_angleZactual = OpFloat(line, "aAngleZactual", 0.0f); - m_angleYfinal = OpFloat(line, "aAngleYfinal", 0.0f); - m_angleZfinal = OpFloat(line, "aAngleZfinal", 0.0f); + m_phase = static_cast< AutoTowerPhase >(line->GetParam("aPhase")->AsInt(ATP_WAIT)); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); + m_targetPos = line->GetParam("aTargetPos")->AsPoint(Math::Vector()); + m_angleYactual = line->GetParam("aAngleYactual")->AsFloat(0.0f); + m_angleZactual = line->GetParam("aAngleZactual")->AsFloat(0.0f); + m_angleYfinal = line->GetParam("aAngleYfinal")->AsFloat(0.0f); + m_angleZfinal = line->GetParam("aAngleZfinal")->AsFloat(0.0f); m_lastUpdateTime = 0.0f; diff --git a/src/object/auto/autotower.h b/src/object/auto/autotower.h index 0158b22e..67982399 100644 --- a/src/object/auto/autotower.h +++ b/src/object/auto/autotower.h @@ -51,8 +51,8 @@ public: bool CreateInterface(bool bSelect); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); protected: void UpdateInterface(float rTime); diff --git a/src/object/brain.cpp b/src/object/brain.cpp index f10faac3..0a723b09 100644 --- a/src/object/brain.cpp +++ b/src/object/brain.cpp @@ -30,6 +30,8 @@ #include "object/motion/motion.h" #include "object/task/taskmanager.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" #include "physics/physics.h" @@ -169,21 +171,18 @@ void CBrain::SetMotion(CMotion* motion) // Saves all parameters of the object. -bool CBrain::Write(char *line) +bool CBrain::Write(CLevelParserLine* line) { - char name[100]; - - sprintf(name, " bVirusActive=%d", m_bActiveVirus); - strcat(line, name); + line->AddParam("bVirusActive", new CLevelParserParam(m_bActiveVirus)); return true; } // Restores all parameters of the object. -bool CBrain::Read(char *line) +bool CBrain::Read(CLevelParserLine* line) { - m_bActiveVirus = OpInt(line, "bVirusActive", 0); + m_bActiveVirus = line->GetParam("bVirusActive")->AsBool(false); return true; } diff --git a/src/object/brain.h b/src/object/brain.h index a0d18698..c1172695 100644 --- a/src/object/brain.h +++ b/src/object/brain.h @@ -41,6 +41,7 @@ class CTaskManager; class CScript; class CRobotMain; class CSoundInterface; +class CLevelParserLine; namespace Ui { class CStudio; @@ -92,8 +93,8 @@ public: bool EventProcess(const Event &event); bool CreateInterface(bool bSelect); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); bool IsBusy(); void SetActivity(bool bMode); diff --git a/src/object/level/parser.cpp b/src/object/level/parser.cpp index 3a0449ab..7c612af6 100644 --- a/src/object/level/parser.cpp +++ b/src/object/level/parser.cpp @@ -24,6 +24,7 @@ #include "common/resources/resourcemanager.h" #include "common/resources/inputstream.h" +#include "common/resources/outputstream.h" #include "object/level/parserexceptions.h" @@ -219,9 +220,22 @@ void CLevelParser::Load() file.close(); } -void CLevelParser::Save(std::string filename) +void CLevelParser::Save() { - assert(false); //TODO + COutputStream file; + file.open(m_filename); + if(!file.is_open()) + throw CLevelParserException("Failed to open file: "+m_filename); + + for(CLevelParserLine* line : m_lines) { + file << line->GetCommand(); + for(auto param : line->GetParams()) { + file << " " << param.first << "=" << param.second->GetValue(); + } + file << "\n"; + } + + file.close(); } const std::string& CLevelParser::GetFilename() diff --git a/src/object/level/parser.h b/src/object/level/parser.h index ca2bf6ff..e0458b5b 100644 --- a/src/object/level/parser.h +++ b/src/object/level/parser.h @@ -51,7 +51,7 @@ public: //! Load file void Load(); //! Save file - void Save(std::string filename); + void Save(); //! Get filename const std::string& GetFilename(); @@ -65,7 +65,6 @@ public: CLevelParserLine* Get(std::string command); private: - std::string m_filename; std::vector m_lines; }; \ No newline at end of file diff --git a/src/object/level/parserline.cpp b/src/object/level/parserline.cpp index e0e8097c..c838b350 100644 --- a/src/object/level/parserline.cpp +++ b/src/object/level/parserline.cpp @@ -43,11 +43,6 @@ CLevelParserLine::~CLevelParserLine() } } -std::string CLevelParserLine::GetLine() -{ - assert(false); //TODO -} - int CLevelParserLine::GetLineNumber() { return m_lineNumber; @@ -87,4 +82,9 @@ void CLevelParserLine::AddParam(std::string name, CLevelParserParam* value) { value->SetLine(this); m_params[name] = value; +} + +const std::map& CLevelParserLine::GetParams() +{ + return m_params; } \ No newline at end of file diff --git a/src/object/level/parserline.h b/src/object/level/parserline.h index 9881ac70..0af0f066 100644 --- a/src/object/level/parserline.h +++ b/src/object/level/parserline.h @@ -37,9 +37,6 @@ public: CLevelParserLine(std::string command); ~CLevelParserLine(); - //! Get line to be saved in level file - std::string GetLine(); - //! Get line number int GetLineNumber(); @@ -53,6 +50,7 @@ public: CLevelParserParam* GetParam(std::string name); void AddParam(std::string name, CLevelParserParam* value); + const std::map& GetParams(); private: CLevelParser* m_level; diff --git a/src/object/level/parserparam.cpp b/src/object/level/parserparam.cpp index 1f81f0e1..a6393623 100644 --- a/src/object/level/parserparam.cpp +++ b/src/object/level/parserparam.cpp @@ -939,6 +939,18 @@ void CLevelParserParam::ParseArray() } } +void CLevelParserParam::LoadArray() +{ + m_value = ""; + bool first = true; + for(auto& value : m_array) { + if(!first) + m_value += ";"; + m_value += value->GetValue(); + first = false; + } +} + const std::vector& CLevelParserParam::AsArray() { if(m_empty) @@ -947,4 +959,56 @@ const std::vector& CLevelParserParam::AsArray() ParseArray(); return m_array; -} \ No newline at end of file +} + +CLevelParserParam::CLevelParserParam(int value) +{ + m_value = boost::lexical_cast(value); +} +CLevelParserParam::CLevelParserParam(float value) +{ + m_value = boost::lexical_cast(value); +} +CLevelParserParam::CLevelParserParam(std::string value) +{ + m_value = "\""+value+"\""; +} +CLevelParserParam::CLevelParserParam(bool value) +{ + m_value = value ? "1" : "0"; +} +CLevelParserParam::CLevelParserParam(Gfx::Color value) +{ + m_array.push_back(new CLevelParserParam(value.r)); + m_array.push_back(new CLevelParserParam(value.g)); + m_array.push_back(new CLevelParserParam(value.b)); + m_array.push_back(new CLevelParserParam(value.a)); + LoadArray(); +} +CLevelParserParam::CLevelParserParam(Math::Point value) +{ + m_array.push_back(new CLevelParserParam(value.x)); + m_array.push_back(new CLevelParserParam(value.y)); + LoadArray(); +} +CLevelParserParam::CLevelParserParam(Math::Vector value) +{ + m_array.push_back(new CLevelParserParam(value.x)); + m_array.push_back(new CLevelParserParam(value.y)); + m_array.push_back(new CLevelParserParam(value.z)); + LoadArray(); +} +CLevelParserParam::CLevelParserParam(ObjectType value) +{ + m_value = FromObjectType(value); +} +CLevelParserParam::CLevelParserParam(Gfx::CameraType value) +{ + m_value = FromCameraType(value); +} +CLevelParserParam::CLevelParserParam(const std::vector& value) +{ + m_array = value; + LoadArray(); +} + diff --git a/src/object/level/parserparam.h b/src/object/level/parserparam.h index f59b40fb..0ef350fb 100644 --- a/src/object/level/parserparam.h +++ b/src/object/level/parserparam.h @@ -45,6 +45,7 @@ public: CLevelParserParam(bool value); CLevelParserParam(Gfx::Color value); CLevelParserParam(Math::Point value); + CLevelParserParam(Math::Vector value); CLevelParserParam(ObjectType value); CLevelParserParam(Gfx::CameraType value); CLevelParserParam(const std::vector& value); @@ -110,6 +111,7 @@ public: private: void ParseArray(); + void LoadArray(); template T Cast(std::string value, std::string requestedType); template T Cast(std::string requestedType); diff --git a/src/object/motion/motion.cpp b/src/object/motion/motion.cpp index 66933178..d7044937 100644 --- a/src/object/motion/motion.cpp +++ b/src/object/motion/motion.cpp @@ -23,6 +23,8 @@ #include "app/app.h" #include "object/robotmain.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" #include "script/cmdtoken.h" @@ -171,31 +173,24 @@ float CMotion::GetParam(int rank) // Saves all parameters of the object. -bool CMotion::Write(char *line) +bool CMotion::Write(CLevelParserLine* line) { - char name[100]; - if ( m_actionType == -1 ) return false; - - sprintf(name, " mType=%d", m_actionType); - strcat(line, name); - - sprintf(name, " mTime=%.2f", m_actionTime); - strcat(line, name); - - sprintf(name, " mProgress=%.2f", m_progress); - strcat(line, name); + + line->AddParam("mType", new CLevelParserParam(m_actionType)); + line->AddParam("mTime", new CLevelParserParam(m_actionTime)); + line->AddParam("mProgress", new CLevelParserParam(m_progress)); return false; } // Restores all parameters of the object. -bool CMotion::Read(char *line) +bool CMotion::Read(CLevelParserLine* line) { - m_actionType = OpInt(line, "mType", -1); - m_actionTime = OpFloat(line, "mTime", 0.0f); - m_progress = OpFloat(line, "mProgress", 0.0f); + m_actionType = line->GetParam("mType")->AsInt(-1); + m_actionTime = line->GetParam("mTime")->AsFloat(0.0f); + m_progress = line->GetParam("mProgress")->AsFloat(0.0f); return false; } diff --git a/src/object/motion/motion.h b/src/object/motion/motion.h index 81350b7d..a116b3fc 100644 --- a/src/object/motion/motion.h +++ b/src/object/motion/motion.h @@ -42,6 +42,7 @@ class CPhysics; class CObject; class CRobotMain; class CSoundInterface; +class CLevelParserLine; class CMotion @@ -62,8 +63,8 @@ public: virtual bool SetParam(int rank, float value); virtual float GetParam(int rank); - virtual bool Write(char *line); - virtual bool Read(char *line); + virtual bool Write(CLevelParserLine* line); + virtual bool Read(CLevelParserLine* line); virtual void SetLinVibration(Math::Vector dir); virtual Math::Vector GetLinVibration(); diff --git a/src/object/object.cpp b/src/object/object.cpp index a64bcb5d..6e386f35 100644 --- a/src/object/object.cpp +++ b/src/object/object.cpp @@ -76,12 +76,17 @@ #include "object/motion/motionworm.h" #include "object/robotmain.h" #include "object/objman.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" +#include "object/level/parserexceptions.h" #include "physics/physics.h" #include "script/cbottoken.h" #include "script/cmdtoken.h" +#include + #define ADJUST_ONBOARD false // true -> adjusts the camera ONBOARD @@ -995,137 +1000,76 @@ int CObject::GetID() // Saves all the parameters of the object. -bool CObject::Write(char *line) +bool CObject::Write(CLevelParserLine* line) { Math::Vector pos; Info info; - char name[100]; float value; int i; - sprintf(name, " camera=%s", GetCamera(GetCameraType())); - strcat(line, name); + line->AddParam("camera", new CLevelParserParam(GetCameraType())); - if ( GetCameraLock() != 0 ) - { - sprintf(name, " cameraLock=%d", GetCameraLock()); - strcat(line, name); - } + if ( GetCameraLock() ) + line->AddParam("cameraLock", new CLevelParserParam(GetCameraLock())); if ( GetEnergy() != 0.0f ) - { - sprintf(name, " energy=%.2f", GetEnergy()); - strcat(line, name); - } + line->AddParam("energy", new CLevelParserParam(GetEnergy())); if ( GetCapacity() != 1.0f ) - { - sprintf(name, " capacity=%.2f", GetCapacity()); - strcat(line, name); - } - + line->AddParam("capacity", new CLevelParserParam(GetCapacity())); + if ( GetShield() != 1.0f ) - { - sprintf(name, " shield=%.2f", GetShield()); - strcat(line, name); - } + line->AddParam("shield", new CLevelParserParam(GetShield())); if ( GetRange() != 1.0f ) - { - sprintf(name, " range=%.2f", GetRange()); - strcat(line, name); - } + line->AddParam("range", new CLevelParserParam(GetRange())); + + if ( !GetSelectable() ) + line->AddParam("selectable", new CLevelParserParam(GetSelectable())); - if ( GetSelectable() != 1 ) - { - sprintf(name, " selectable=%d", GetSelectable()); - strcat(line, name); - } + if ( !GetEnable() ) + line->AddParam("enable", new CLevelParserParam(GetEnable())); - if ( GetEnable() != 1 ) - { - sprintf(name, " enable=%d", GetEnable()); - strcat(line, name); - } + if ( GetFixed() ) + line->AddParam("fixed", new CLevelParserParam(GetFixed())); - if ( GetFixed() != 0 ) - { - sprintf(name, " fixed=%d", GetFixed()); - strcat(line, name); - } + if ( !GetClip() ) + line->AddParam("clip", new CLevelParserParam(GetClip())); - if ( GetClip() != 1 ) - { - sprintf(name, " clip=%d", GetClip()); - strcat(line, name); - } + if ( GetLock() ) + line->AddParam("lock", new CLevelParserParam(GetLock())); - if ( GetLock() != 0 ) + if ( GetProxyActivate() ) { - sprintf(name, " lock=%d", GetLock()); - strcat(line, name); - } - - if ( GetProxyActivate() != 0 ) - { - sprintf(name, " proxyActivate=%d", GetProxyActivate()); - strcat(line, name); - - sprintf(name, " proxyDistance=%.2f", GetProxyDistance()/g_unit); - strcat(line, name); + line->AddParam("proxyActivate", new CLevelParserParam(GetProxyActivate())); + line->AddParam("proxyDistance", new CLevelParserParam(GetProxyDistance()/g_unit)); } if ( GetMagnifyDamage() != 1.0f ) - { - sprintf(name, " magnifyDamage=%.2f", GetMagnifyDamage()); - strcat(line, name); - } + line->AddParam("magnifyDamage", new CLevelParserParam(GetMagnifyDamage())); if ( GetGunGoalV() != 0.0f ) - { - sprintf(name, " aimV=%.2f", GetGunGoalV()); - strcat(line, name); - } + line->AddParam("aimV", new CLevelParserParam(GetGunGoalV())); + if ( GetGunGoalH() != 0.0f ) - { - sprintf(name, " aimH=%.2f", GetGunGoalH()); - strcat(line, name); - } + line->AddParam("aimH", new CLevelParserParam(GetGunGoalH())); if ( GetParam() != 0.0f ) - { - sprintf(name, " param=%.2f", GetParam()); - strcat(line, name); - } + line->AddParam("param", new CLevelParserParam(GetParam())); if ( GetResetCap() != 0 ) { - sprintf(name, " resetCap=%d", GetResetCap()); - strcat(line, name); - - pos = GetResetPosition()/g_unit; - sprintf(name, " resetPos=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); - strcat(line, name); - - pos = GetResetAngle()/(Math::PI/180.0f); - sprintf(name, " resetAngle=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); - strcat(line, name); - - sprintf(name, " resetRun=%d", GetResetRun()); - strcat(line, name); + line->AddParam("resetCap", new CLevelParserParam(static_cast(GetResetCap()))); + line->AddParam("resetPos", new CLevelParserParam(GetResetPosition()/g_unit)); + line->AddParam("resetAngle", new CLevelParserParam(GetResetAngle()/(Math::PI/180.0f))); + line->AddParam("resetRun", new CLevelParserParam(GetResetRun())); } - if ( m_bVirusMode != 0 ) - { - sprintf(name, " virusMode=%d", m_bVirusMode); - strcat(line, name); - } + if ( m_bVirusMode ) + line->AddParam("virusMode", new CLevelParserParam(m_bVirusMode)); if ( m_virusTime != 0.0f ) - { - sprintf(name, " virusTime=%.2f", m_virusTime); - strcat(line, name); - } + line->AddParam("virusTime", new CLevelParserParam(m_virusTime)); // Puts information in terminal (OBJECT_INFO). for ( i=0 ; iAddParam("info"+boost::lexical_cast(i+1), new CLevelParserParam(std::string(info.name)+"="+boost::lexical_cast(info.value))); } // Sets the parameters of the command line. + std::vector cmdline; for ( i=0 ; i 0) + line->AddParam("cmdline", new CLevelParserParam(cmdline)); - if ( m_motion != 0 ) + if ( m_motion != nullptr ) { m_motion->Write(line); } - if ( m_brain != 0 ) + if ( m_brain != nullptr ) { m_brain->Write(line); } - if ( m_physics != 0 ) + if ( m_physics != nullptr ) { m_physics->Write(line); } - if ( m_auto != 0 ) + if ( m_auto != nullptr ) { m_auto->Write(line); } @@ -1173,87 +1117,91 @@ bool CObject::Write(char *line) // Returns all parameters of the object. -bool CObject::Read(char *line) +bool CObject::Read(CLevelParserLine* line) { Math::Vector pos, dir; - Info info; Gfx::CameraType cType; - char op[20]; - char text[100]; - char* p; - float value; int i; - cType = OpCamera(line, "camera"); + cType = line->GetParam("camera")->AsCameraType(Gfx::CAM_TYPE_NULL); if ( cType != Gfx::CAM_TYPE_NULL ) { SetCameraType(cType); } - SetCameraLock(OpInt(line, "cameraLock", 0)); - SetEnergy(OpFloat(line, "energy", 0.0f)); - SetCapacity(OpFloat(line, "capacity", 1.0f)); - SetShield(OpFloat(line, "shield", 1.0f)); - SetRange(OpFloat(line, "range", 1.0f)); - SetSelectable(OpInt(line, "selectable", 1)); - SetEnable(OpInt(line, "enable", 1)); - SetFixed(OpInt(line, "fixed", 0)); - SetClip(OpInt(line, "clip", 1)); - SetLock(OpInt(line, "lock", 0)); - SetProxyActivate(OpInt(line, "proxyActivate", 0)); - SetProxyDistance(OpFloat(line, "proxyDistance", 15.0f)*g_unit); - SetRange(OpFloat(line, "range", 30.0f)); - SetMagnifyDamage(OpFloat(line, "magnifyDamage", 1.0f)); - SetGunGoalV(OpFloat(line, "aimV", 0.0f)); - SetGunGoalH(OpFloat(line, "aimH", 0.0f)); - SetParam(OpFloat(line, "param", 0.0f)); - SetResetCap(static_cast(OpInt(line, "resetCap", 0))); - SetResetPosition(OpDir(line, "resetPos")*g_unit); - SetResetAngle(OpDir(line, "resetAngle")*(Math::PI/180.0f)); - SetResetRun(OpInt(line, "resetRun", 0)); - m_bBurn = OpInt(line, "burnMode", 0); - m_bVirusMode = OpInt(line, "virusMode", 0); - m_virusTime = OpFloat(line, "virusTime", 0.0f); + SetCameraLock(line->GetParam("cameraLock")->AsBool(false)); + SetEnergy(line->GetParam("energy")->AsFloat(0.0f)); + SetCapacity(line->GetParam("capacity")->AsFloat(1.0f)); + SetShield(line->GetParam("shield")->AsFloat(1.0f)); + SetRange(line->GetParam("range")->AsFloat(1.0f)); + SetSelectable(line->GetParam("selectable")->AsBool(true)); + SetEnable(line->GetParam("enable")->AsBool(true)); + SetFixed(line->GetParam("fixed")->AsBool(false)); + SetClip(line->GetParam("clip")->AsBool(true)); + SetLock(line->GetParam("lock")->AsBool(false)); + SetProxyActivate(line->GetParam("proxyActivate")->AsBool(false)); + SetProxyDistance(line->GetParam("proxyDistance")->AsFloat(15.0f)*g_unit); + SetRange(line->GetParam("range")->AsFloat(30.0f)); + SetMagnifyDamage(line->GetParam("magnifyDamage")->AsFloat(1.0f)); + SetGunGoalV(line->GetParam("aimV")->AsFloat(0.0f)); + SetGunGoalH(line->GetParam("aimH")->AsFloat(0.0f)); + SetParam(line->GetParam("param")->AsFloat(0.0f)); + SetResetCap(static_cast(line->GetParam("resetCap")->AsInt(0))); + SetResetPosition(line->GetParam("resetPos")->AsPoint(Math::Vector())*g_unit); + SetResetAngle(line->GetParam("resetAngle")->AsPoint(Math::Vector())*(Math::PI/180.0f)); + SetResetRun(line->GetParam("resetRun")->AsInt(0)); + m_bBurn = line->GetParam("burnMode")->AsBool(false); + m_bVirusMode = line->GetParam("virusMode")->AsBool(false); + m_virusTime = line->GetParam("virusTime")->AsFloat(0.0f); // Puts information in terminal (OBJECT_INFO). for ( i=0 ; iReadProgram(i, filename); if (!brain->GetCompile(i)) nbError++; } @@ -5478,23 +5457,13 @@ void CRobotMain::LoadFileScript(CObject *obj, const char* filename, int objRank, ObjectType type = obj->GetType(); if (type == OBJECT_HUMAN) return; + std::string dirname = filename; + dirname = dirname.substr(0, dirname.find_last_of("/")); - std::string fnstr = filename; - std::string savedir = CResourceManager::GetSaveLocation()+"/"; - boost::replace_all(fnstr, "\\", "/"); - boost::replace_all(savedir, "\\", "/"); - boost::replace_all(fnstr, savedir, ""); //TODO: Refactor to get physfs path here - //TODO: Refactor to std::string - char fn[MAX_FNAME]; - strcpy(fn, fnstr.c_str()); - char* ldir = SearchLastDir(fn); - if (ldir == 0) return; - + char fn[MAX_FNAME]; //TODO: Refactor to std::string for (int i = 0; i < BRAINMAXSCRIPT; i++) { - if (brain->GetCompile(i)) continue; - - sprintf(ldir, "/prog%.3d%.1d.txt", objRank, i); + sprintf(fn, "%s/prog%.3d%.1d.txt", dirname.c_str(), objRank, i); brain->ReadProgram(i, fn); if (!brain->GetCompile(i)) nbError++; } @@ -5536,7 +5505,7 @@ void CRobotMain::SaveOneScript(CObject *obj) { char filename[MAX_FNAME]; sprintf(filename, "%s/%s/%c%.3d%.3d%.1d.txt", - GetPHYSFSSavegameDir(), m_gamerName.c_str(), name[0], rank, objRank, i); + GetSavegameDir(), m_gamerName.c_str(), name[0], rank, objRank, i); brain->WriteProgram(i, filename); } } @@ -5552,21 +5521,14 @@ void CRobotMain::SaveFileScript(CObject *obj, const char* filename, int objRank) ObjectType type = obj->GetType(); if (type == OBJECT_HUMAN) return; - - std::string fnstr = filename; - std::string savedir = CResourceManager::GetSaveLocation()+"/"; - boost::replace_all(fnstr, "\\", "/"); - boost::replace_all(savedir, "\\", "/"); - boost::replace_all(fnstr, savedir, ""); //TODO: Refactor to get physfs path here - //TODO: Refactor to std::string - char fn[MAX_FNAME]; - strcpy(fn, fnstr.c_str()); - char* ldir = SearchLastDir(fn); - if (ldir == 0) return; - + + std::string dirname = filename; + dirname = dirname.substr(0, dirname.find_last_of("/")); + + char fn[MAX_FNAME]; //TODO: Refactor to std::string for (int i = 0; i < BRAINMAXSCRIPT; i++) { - sprintf(ldir, "/prog%.3d%.1d.txt", objRank, i); + sprintf(fn, "%s/prog%.3d%.1d.txt", dirname.c_str(), objRank, i); brain->WriteProgram(i, fn); } } @@ -5665,37 +5627,17 @@ bool CRobotMain::IsBusy() } //! Writes an object into the backup file -void CRobotMain::IOWriteObject(FILE *file, CObject* obj, const char *cmd) +void CRobotMain::IOWriteObject(CLevelParserLine* line, CObject* obj) { if (obj->GetType() == OBJECT_FIX) return; - SetNumericLocale(); - - char line[3000]; - char name[100]; - - strcpy(line, cmd); - - sprintf(name, " type=%s", GetTypeObject(obj->GetType())); - strcat(line, name); - - sprintf(name, " id=%d", obj->GetID()); - strcat(line, name); + line->AddParam("type", new CLevelParserParam(obj->GetType())); + line->AddParam("id", new CLevelParserParam(obj->GetID())); + line->AddParam("pos", new CLevelParserParam(obj->GetPosition(0)/g_unit)); + line->AddParam("angle", new CLevelParserParam(obj->GetAngle(0)/(Math::PI/180.0f))); + line->AddParam("zoom", new CLevelParserParam(obj->GetZoom(0))); Math::Vector pos; - - pos = obj->GetPosition(0)/g_unit; - sprintf(name, " pos=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); - strcat(line, name); - - pos = obj->GetAngle(0)/(Math::PI/180.0f); - sprintf(name, " angle=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); - strcat(line, name); - - pos = obj->GetZoom(0); - sprintf(name, " zoom=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); - strcat(line, name); - for (int i = 1; i < OBJECTMAXPART; i++) { if (obj->GetObjectRank(i) == -1) continue; @@ -5704,104 +5646,94 @@ void CRobotMain::IOWriteObject(FILE *file, CObject* obj, const char *cmd) if (pos.x != 0.0f || pos.y != 0.0f || pos.z != 0.0f) { pos /= g_unit; - sprintf(name, " p%d=%.2f;%.2f;%.2f", i, pos.x, pos.y, pos.z); - strcat(line, name); + line->AddParam("p"+boost::lexical_cast(i), new CLevelParserParam(pos)); } pos = obj->GetAngle(i); if (pos.x != 0.0f || pos.y != 0.0f || pos.z != 0.0f) { pos /= (Math::PI/180.0f); - sprintf(name, " a%d=%.2f;%.2f;%.2f", i, pos.x, pos.y, pos.z); - strcat(line, name); + line->AddParam("a"+boost::lexical_cast(i), new CLevelParserParam(pos)); } pos = obj->GetZoom(i); if (pos.x != 1.0f || pos.y != 1.0f || pos.z != 1.0f) { - sprintf(name, " z%d=%.2f;%.2f;%.2f", i, pos.x, pos.y, pos.z); - strcat(line, name); + line->AddParam("z"+boost::lexical_cast(i), new CLevelParserParam(pos)); } } - sprintf(name, " trainer=%d", obj->GetTrainer()); - strcat(line, name); + line->AddParam("trainer", new CLevelParserParam(obj->GetTrainer())); + line->AddParam("ignoreBuildCheck", new CLevelParserParam(obj->GetIgnoreBuildCheck())); + line->AddParam("option", new CLevelParserParam(obj->GetOption())); + if (obj == m_infoObject) + line->AddParam("select", new CLevelParserParam(1)); - sprintf(name, " ignoreBuildCheck=%d", obj->GetIgnoreBuildCheck()); - strcat(line, name); - - sprintf(name, " option=%d", obj->GetOption()); - strcat(line, name); - - if (obj == m_infoObject) // selects object? - { - sprintf(name, " select=1"); - strcat(line, name); - } - obj->Write(line); - - if (obj->GetType() == OBJECT_BASE) - { - sprintf(name, " run=3"); // stops and open (PARAM_FIXSCENE) - strcat(line, name); - } - + + if(obj->GetType() == OBJECT_BASE) + line->AddParam("run", new CLevelParserParam(3)); // stops and open (PARAM_FIXSCENE) + CBrain* brain = obj->GetBrain(); if (brain != nullptr) { int run = brain->GetProgram(); if (run != -1) { - sprintf(name, " run=%d", run+1); - strcat(line, name); + line->AddParam("run", new CLevelParserParam(run+1)); } } - - strcat(line, "\n"); - fputs(line, file); - - RestoreNumericLocale(); } //! Saves the current game bool CRobotMain::IOWriteScene(const char *filename, const char *filecbot, char *info) { - FILE* file = fopen(filename, "w"); - if (file == NULL) return false; + std::string fnstr = filename; + std::string savedir = CResourceManager::GetSaveLocation()+"/"; + boost::replace_all(fnstr, "\\", "/"); + boost::replace_all(savedir, "\\", "/"); + boost::replace_all(fnstr, savedir, ""); //TODO: Refactor to get physfs path here + + CLevelParser* level = new CLevelParser(fnstr); + CLevelParserLine* line; - SetNumericLocale(); - - char line[500]; - - sprintf(line, "Title text=\"%s\"\n", info); - fputs(line, file); - - sprintf(line, "Version maj=%d min=%d\n", 0, 1); - fputs(line, file); + line = new CLevelParserLine("Title"); + line->AddParam("text", new CLevelParserParam(std::string(info))); + level->AddLine(line); + + //TODO: Do we need that? It's not used anyway + line = new CLevelParserLine("Version"); + line->AddParam("maj", new CLevelParserParam(0)); + line->AddParam("min", new CLevelParserParam(1)); + level->AddLine(line); char* name = m_dialog->GetSceneName(); - if (strcmp(name, "user") == 0) + line = new CLevelParserLine("Mission"); + line->AddParam("base", new CLevelParserParam(std::string(name))); + line->AddParam("rank", new CLevelParserParam(m_dialog->GetSceneRank())); + if (std::string(name) == "custom") { - sprintf(line, "Mission base=\"%s\" rank=%.3d dir=\"%s\"\n", name, m_dialog->GetSceneRank(), m_dialog->GetSceneDir()); + line->AddParam("dir", new CLevelParserParam(std::string(m_dialog->GetSceneDir()))); } - else - { - sprintf(line, "Mission base=\"%s\" rank=%.3d\n", name, m_dialog->GetSceneRank()); - } - fputs(line, file); + level->AddLine(line); - sprintf(line, "Map zoom=%.2f\n", m_map->GetZoomMap()); - fputs(line, file); + line = new CLevelParserLine("Map"); + line->AddParam("zoom", new CLevelParserParam(m_map->GetZoomMap())); + level->AddLine(line); - sprintf(line, "DoneResearch bits=%d\n", static_cast(g_researchDone)); - fputs(line, file); + line = new CLevelParserLine("DoneResearch"); + line->AddParam("bits", new CLevelParserParam(static_cast(g_researchDone))); + level->AddLine(line); float sleep, delay, magnetic, progress; if (m_lightning->GetStatus(sleep, delay, magnetic, progress)) { - sprintf(line, "BlitzMode sleep=%.2f delay=%.2f magnetic=%.2f progress=%.2f\n", sleep, delay, magnetic/g_unit, progress); - fputs(line, file); + line = new CLevelParserLine("BlitzMode"); + line->AddParam("sleep", new CLevelParserParam(sleep)); + line->AddParam("delay", new CLevelParserParam(delay)); + line->AddParam("magnetic", new CLevelParserParam(magnetic/g_unit)); + line->AddParam("progress", new CLevelParserParam(progress)); + level->AddLine(line); } CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); @@ -5822,23 +5754,35 @@ bool CRobotMain::IOWriteScene(const char *filename, const char *filecbot, char * CObject* power = obj->GetPower(); CObject* fret = obj->GetFret(); - if (fret != nullptr) // object transported? - IOWriteObject(file, fret, "CreateFret"); + if (fret != nullptr){ // object transported? + line = new CLevelParserLine("CreateFret"); + IOWriteObject(line, fret); + level->AddLine(line); + } - if (power != nullptr) // battery transported? - IOWriteObject(file, power, "CreatePower"); - - IOWriteObject(file, obj, "CreateObject"); + if (power != nullptr) { // battery transported? + line = new CLevelParserLine("CreatePower"); + IOWriteObject(line, power); + level->AddLine(line); + } + + line = new CLevelParserLine("CreateObject"); + IOWriteObject(line, obj); + level->AddLine(line); SaveFileScript(obj, filename, objRank++); } - fclose(file); + try { + level->Save(); + } catch(CLevelParserException& e) { + CLogger::GetInstancePointer()->Error("Failed to save level state - %s\n", e.what()); + delete level; + return false; + } + delete level; - RestoreNumericLocale(); - -#if CBOT_STACK // Writes the file of stacks of execution. - file = fOpen(filecbot, "wb"); + FILE* file = fOpen(filecbot, "wb"); if (file == NULL) return false; long version = 1; @@ -5862,35 +5806,30 @@ bool CRobotMain::IOWriteScene(const char *filename, const char *filecbot, char * } CBotClass::SaveStaticState(file); fClose(file); -#endif m_delayWriteMessage = 4; // displays message in 3 frames return true; } //! Resumes the game -CObject* CRobotMain::IOReadObject(char *line, const char* filename, int objRank) +CObject* CRobotMain::IOReadObject(CLevelParserLine *line, const char* filename, int objRank) { - Math::Vector pos = OpDir(line, "pos")*g_unit; - Math::Vector dir = OpDir(line, "angle")*(Math::PI/180.0f); - Math::Vector zoom = OpDir(line, "zoom"); + Math::Vector pos = line->GetParam("pos")->AsPoint()*g_unit; + Math::Vector dir = line->GetParam("angle")->AsPoint()*(Math::PI/180.0f); + Math::Vector zoom = line->GetParam("zoom")->AsPoint(); - ObjectType type = OpTypeObject(line, "type", OBJECT_NULL); - int id = OpInt(line, "id", 0); - if (type == OBJECT_NULL) - return nullptr; + ObjectType type = line->GetParam("type")->AsObjectType(); + int id = line->GetParam("id")->AsInt(); - SetNumericLocale(); - - int trainer = OpInt(line, "trainer", 0); - int toy = OpInt(line, "toy", 0); - int option = OpInt(line, "option", 0); + bool trainer = line->GetParam("trainer")->AsBool(false); + bool toy = line->GetParam("toy")->AsBool(false); + int option = line->GetParam("option")->AsInt(0); CObject* obj = CObjectManager::GetInstancePointer()->CreateObject(pos, dir.y, type, 0.0f, 1.0f, 0.0f, trainer, toy, option); obj->SetDefRank(objRank); obj->SetPosition(0, pos); obj->SetAngle(0, dir); - obj->SetIgnoreBuildCheck(OpInt(line, "ignoreBuildCheck", 0)); + obj->SetIgnoreBuildCheck(line->GetParam("ignoreBuildCheck")->AsBool(false)); obj->SetID(id); if (g_id < id) g_id = id; @@ -5901,23 +5840,19 @@ CObject* CRobotMain::IOReadObject(char *line, const char* filename, int objRank) { if (obj->GetObjectRank(i) == -1) continue; - char op[10]; - sprintf(op, "p%d", i); - pos = OpDir(line, op); + pos = line->GetParam(std::string("p")+boost::lexical_cast(i))->AsPoint(Math::Vector()); if (pos.x != 0.0f || pos.y != 0.0f || pos.z != 0.0f) { obj->SetPosition(i, pos*g_unit); } - - sprintf(op, "a%d", i); - dir = OpDir(line, op); + + dir = line->GetParam(std::string("a")+boost::lexical_cast(i))->AsPoint(Math::Vector()); if (dir.x != 0.0f || dir.y != 0.0f || dir.z != 0.0f) { obj->SetAngle(i, dir*(Math::PI/180.0f)); } - - sprintf(op, "z%d", i); - zoom = OpDir(line, op); + + zoom = line->GetParam(std::string("z")+boost::lexical_cast(i))->AsPoint(Math::Vector()); if (zoom.x != 0.0f || zoom.y != 0.0f || zoom.z != 0.0f) { obj->SetZoom(i, zoom); @@ -5928,84 +5863,62 @@ CObject* CRobotMain::IOReadObject(char *line, const char* filename, int objRank) obj->Read(line); -#if CBOT_STACK -#else - LoadFileScript(obj, filename, objRank, i); -#endif - - int run = OpInt(line, "run", -1); + int run = line->GetParam("run")->AsInt(-1); if (run != -1) { -#if CBOT_STACK -#else - CBrain* brain = obj->GetBrain(); - if (brain != nullptr) - brain->RunProgram(run-1); // starts the program -#endif - CAuto* automat = obj->GetAuto(); if (automat != nullptr) automat->Start(run); // starts the film } - RestoreNumericLocale(); - return obj; } //! Resumes some part of the game CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot) { + std::string fnstr = filename; + std::string savedir = CResourceManager::GetSaveLocation()+"/"; + boost::replace_all(fnstr, "\\", "/"); + boost::replace_all(savedir, "\\", "/"); + boost::replace_all(fnstr, savedir, ""); //TODO: Refactor to get physfs path here + + CLevelParser* level = new CLevelParser(fnstr); + level->Load(); + m_base = nullptr; - - FILE* file = fopen(filename, "r"); - if (file == NULL) return 0; - - SetNumericLocale(); - CObject* fret = nullptr; CObject* power = nullptr; CObject* sel = nullptr; int objRank = 0; - char line[3000]; - while (fgets(line, 3000, file) != NULL) + for(auto& line : level->GetLines()) { - for (int i = 0; i < 3000; i++) + if (line->GetCommand() == "Map") + m_map->ZoomMap(line->GetParam("zoom")->AsFloat()); + + if (line->GetCommand() == "DoneResearch") + g_researchDone = line->GetParam("bits")->AsInt(); + + if (line->GetCommand() == "BlitzMode") { - if (line[i] == '\t') line[i] = ' '; // replace tab by space - if (line[i] == '/' && line[i+1] == '/') - { - line[i] = 0; - break; - } - } - - if (Cmd(line, "Map")) - m_map->ZoomMap(OpFloat(line, "zoom", 1.0f)); - - if (Cmd(line, "DoneResearch")) - g_researchDone = OpInt(line, "bits", 0); - - if (Cmd(line, "BlitzMode")) - { - float sleep = OpFloat(line, "sleep", 0.0f); - float delay = OpFloat(line, "delay", 3.0f); - float magnetic = OpFloat(line, "magnetic", 50.0f)*g_unit; - float progress = OpFloat(line, "progress", 0.0f); + float sleep = line->GetParam("sleep")->AsFloat(); + float delay = line->GetParam("delay")->AsFloat(); + float magnetic = line->GetParam("magnetic")->AsFloat()*g_unit; + float progress = line->GetParam("progress")->AsFloat(); m_lightning->SetStatus(sleep, delay, magnetic, progress); } - if (Cmd(line, "CreateFret")) + if (line->GetCommand() == "CreateFret") fret = IOReadObject(line, filename, -1); - if (Cmd(line, "CreatePower")) + if (line->GetCommand() == "CreatePower") power = IOReadObject(line, filename, -1); - if (Cmd(line, "CreateObject")) + if (line->GetCommand() == "CreateObject") { CObject* obj = IOReadObject(line, filename, objRank++); - if (OpInt(line, "select", 0)) + if (line->GetParam("select")->AsBool(false)) sel = obj; if (fret != nullptr) @@ -6026,9 +5939,8 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot) power = nullptr; } } - fclose(file); + delete level; -#if CBOT_STACK CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); // Compiles scripts. @@ -6053,7 +5965,7 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot) while (nbError > 0 && nbError != lastError); // Reads the file of stacks of execution. - file = fOpen(filecbot, "rb"); + FILE* file = fOpen(filecbot, "rb"); if (file != NULL) { long version; @@ -6082,9 +5994,6 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot) CBotClass::RestoreStaticState(file); fClose(file); } -#endif - - RestoreNumericLocale(); return sel; } @@ -6098,15 +6007,17 @@ void CRobotMain::WriteFreeParam() if (m_gamerName == "") return; - char filename[MAX_FNAME]; - sprintf(filename, "%s/%s/research.gam", GetSavegameDir(), m_gamerName.c_str()); - FILE* file = fopen(filename, "w"); - if (file == NULL) return; - - char line[100]; - sprintf(line, "research=%d build=%d\n", m_freeResearch, m_freeBuild); - fputs(line, file); - fclose(file); + COutputStream file; + file.open(std::string(GetSavegameDir())+"/"+m_gamerName+"/research.gam"); + if(!file.is_open()) + { + CLogger::GetInstancePointer()->Error("Unable to write free game unlock state\n"); + return; + } + + file << "research=" << m_freeResearch << " build=" << m_freeBuild << "\n"; + + file.close(); } //! Reads the global parameters for free play @@ -6117,16 +6028,23 @@ void CRobotMain::ReadFreeParam() if (m_gamerName == "") return; - char filename[MAX_FNAME]; - sprintf(filename, "%s/%s/research.gam", GetSavegameDir(), m_gamerName.c_str()); - FILE* file = fopen(filename, "r"); - if (file == NULL) return; + if(!CResourceManager::Exists(std::string(GetSavegameDir())+"/"+m_gamerName+"/research.gam")) + return; + + CInputStream file; + file.open(std::string(GetSavegameDir())+"/"+m_gamerName+"/research.gam"); + if(!file.is_open()) + { + CLogger::GetInstancePointer()->Error("Unable to read free game unlock state\n"); + return; + } - char line[100]; - if (fgets(line, 100, file) != NULL) - sscanf(line, "research=%d build=%d\n", &m_freeResearch, &m_freeBuild); + std::string line; + std::getline(file, line); + + sscanf(line.c_str(), "research=%d build=%d\n", &m_freeResearch, &m_freeBuild); - fclose(file); + file.close(); } @@ -6694,12 +6612,6 @@ bool CRobotMain::GetRadar() return false; } -//TODO: Use PHYSFS everywhere -const char* CRobotMain::GetPHYSFSSavegameDir() -{ - return m_dialog->GetPHYSFSSavegameDir().c_str(); -} - const char* CRobotMain::GetSavegameDir() { return m_dialog->GetSavegameDir().c_str(); @@ -6986,20 +6898,6 @@ void CRobotMain::ClearInterface() m_tooltipName.clear(); // really removes the tooltip } -void CRobotMain::SetNumericLocale() -{ - char *locale = setlocale(LC_NUMERIC, nullptr); - if (locale != nullptr) - m_oldLocale = locale; - - setlocale(LC_NUMERIC, "C"); -} - -void CRobotMain::RestoreNumericLocale() -{ - setlocale(LC_NUMERIC, m_oldLocale.c_str()); -} - void CRobotMain::DisplayError(Error err, CObject* pObj, float time) { m_displayText->DisplayError(err, pObj, time); diff --git a/src/object/robotmain.h b/src/object/robotmain.h index 9522c2b2..1affd1f6 100644 --- a/src/object/robotmain.h +++ b/src/object/robotmain.h @@ -76,6 +76,7 @@ enum Phase class CEventQueue; class CSoundInterface; +class CLevelParserLine; namespace Gfx { class CEngine; @@ -331,7 +332,6 @@ public: bool GetSceneSoluce(); bool GetShowAll(); bool GetRadar(); - const char* GetPHYSFSSavegameDir(); const char* GetSavegameDir(); const char* GetPublicDir(); const char* GetFilesDir(); @@ -383,14 +383,11 @@ public: bool IsBusy(); bool IOWriteScene(const char *filename, const char *filecbot, char *info); CObject* IOReadScene(const char *filename, const char *filecbot); - void IOWriteObject(FILE *file, CObject* pObj, const char *cmd); - CObject* IOReadObject(char *line, const char* filename, int objRank); + void IOWriteObject(CLevelParserLine *line, CObject* obj); + CObject* IOReadObject(CLevelParserLine *line, const char* filename, int objRank); int CreateSpot(Math::Vector pos, Gfx::Color color); - void SetNumericLocale(); - void RestoreNumericLocale(); - CObject* GetSelect(); void DisplayError(Error err, CObject* pObj, float time=10.0f); @@ -588,8 +585,6 @@ protected: Gfx::Color m_colorRefWater; Gfx::Color m_colorNewWater; float m_colorShiftWater; - - std::string m_oldLocale; bool m_missionTimerEnabled; bool m_missionTimerStarted; diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index 6dd9d321..6de35dc1 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -40,6 +40,8 @@ #include "object/motion/motion.h" #include "object/motion/motionhuman.h" #include "object/task/task.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" #include "script/cmdtoken.h" @@ -171,20 +173,14 @@ PhysicsType CPhysics::GetType() // Saves all parameters of the object. -bool CPhysics::Write(char *line) +bool CPhysics::Write(CLevelParserLine* line) { - char name[100]; - - sprintf(name, " motor=%.2f;%.2f;%.2f", m_motorSpeed.x, m_motorSpeed.y, m_motorSpeed.z); - strcat(line, name); + line->AddParam("motor", new CLevelParserParam(m_motorSpeed)); if ( m_type == TYPE_FLYING ) { - sprintf(name, " reactorRange=%.2f", GetReactorRange()); - strcat(line, name); - - sprintf(name, " land=%d", GetLand()); - strcat(line, name); + line->AddParam("reactorRange", new CLevelParserParam(GetReactorRange())); + line->AddParam("land", new CLevelParserParam(GetLand())); } return true; @@ -192,14 +188,14 @@ bool CPhysics::Write(char *line) // Restores all parameters of the object. -bool CPhysics::Read(char *line) +bool CPhysics::Read(CLevelParserLine* line) { - m_motorSpeed = OpDir(line, "motor"); + m_motorSpeed = line->GetParam("motor")->AsPoint(); if ( m_type == TYPE_FLYING ) { - SetReactorRange(OpFloat(line, "reactorRange", 0.0f)); - SetLand(OpInt(line, "land", 0)); + SetReactorRange(line->GetParam("reactorRange")->AsFloat()); + SetLand(line->GetParam("land")->AsBool()); } return true; diff --git a/src/physics/physics.h b/src/physics/physics.h index ace5b58d..e8996aee 100644 --- a/src/physics/physics.h +++ b/src/physics/physics.h @@ -36,6 +36,7 @@ class CObject; class CBrain; class CMotion; class CSoundInterface; +class CLevelParserLine; namespace Gfx { class CCamera; @@ -110,8 +111,8 @@ public: void SetType(PhysicsType type); PhysicsType GetType(); - bool Write(char *line); - bool Read(char *line); + bool Write(CLevelParserLine* line); + bool Read(CLevelParserLine* line); void SetGravity(float value); float GetGravity(); diff --git a/src/ui/maindialog.cpp b/src/ui/maindialog.cpp index 0bb1e369..829fab49 100644 --- a/src/ui/maindialog.cpp +++ b/src/ui/maindialog.cpp @@ -63,8 +63,6 @@ #include #include #include -#include -#include //TODO Get rid of all sprintf's @@ -115,8 +113,6 @@ static int perso_color[3*10*3] = 0, 0, 0, // }; -namespace fs = boost::filesystem; - // Constructor of robot application. CMainDialog::CMainDialog() @@ -183,9 +179,8 @@ CMainDialog::CMainDialog() } m_savegameDir = "savegame"; - m_publicDir = CResourceManager::GetSaveLocation()+"/program"; //TODO: Refactor to use PHYSFS - m_filesDir = CResourceManager::GetSaveLocation()+"/files"; //TODO: Refactor to use PHYSFS - CLogger::GetInstancePointer()->Trace("Savegame path: normal=%s, physfs=%s\n", GetSavegameDir().c_str(), GetPHYSFSSavegameDir().c_str()); + m_publicDir = "program"; + m_filesDir = "files"; m_setupFull = m_app->GetVideoConfig().fullScreen; @@ -3336,50 +3331,16 @@ std::string & CMainDialog::GetFilesDir() void CMainDialog::ReadNameList() { - CWindow* pw; - CList* pl; - //struct _finddata_t fBuffer; - char dir[MAX_FNAME]; - // char filenames[MAX_FNAME][100]; - std::vector fileNames; - - pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); - if ( pw == 0 ) return; - pl = static_cast(pw->SearchControl(EVENT_INTERFACE_NLIST)); - if ( pl == 0 ) return; + CWindow* pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); + if (pw == nullptr) return; + CList* pl = static_cast(pw->SearchControl(EVENT_INTERFACE_NLIST)); + if (pl == nullptr) return; pl->Flush(); - - try + auto userSaveDirs = CResourceManager::ListDirectories(m_savegameDir); + for (int i = 0; i < static_cast(userSaveDirs.size()); ++i) { - if (! fs::exists(GetSavegameDir()) && fs::is_directory(GetSavegameDir())) - { - GetLogger()->Error("Savegame dir does not exist %s\n",dir); - } - else - { - fs::directory_iterator dirIt(GetSavegameDir()), dirEndIt; - - for (; dirIt != dirEndIt; ++dirIt) - { - const fs::path& p = *dirIt; - if (fs::is_directory(p)) - { - fileNames.push_back(p.leaf().string()); - } - } - } - } - catch (std::exception & e) - { - GetLogger()->Error("Error on listing savegame directory : %s\n", e.what()); - return; - } - - - for (size_t i=0 ; iSetItemName(i, fileNames.at(i).c_str()); + pl->SetItemName(i, userSaveDirs.at(i).c_str()); } } @@ -3562,7 +3523,6 @@ void CMainDialog::NameCreate() CWindow* pw; CEdit* pe; char name[100]; - std::string dir; char c; int len, i, j; @@ -3603,16 +3563,10 @@ void CMainDialog::NameCreate() return; } - - if(!CResourceManager::DirectoryExists(GetPHYSFSSavegameDir())) - CResourceManager::CreateDirectory(GetPHYSFSSavegameDir()); - - dir = GetSavegameDir() + "/" + name; - if (!fs::exists(dir)) + std::string userSaveDir = m_savegameDir + "/" + name; + if (!CResourceManager::DirectoryExists(userSaveDir)) { - fs::create_directories(dir); - if(!CResourceManager::DirectoryExists(GetPHYSFSSavegameDir()+"/"+name)) - CResourceManager::CreateDirectory(GetPHYSFSSavegameDir()+"/"+name); + CResourceManager::CreateDirectory(userSaveDir); } else { @@ -3629,58 +3583,26 @@ void CMainDialog::NameCreate() m_main->ChangePhase(PHASE_INIT); } -// Deletes a folder and all its offspring. - -bool RemoveDir(char *dirName) -{ - try - { - - if (!fs::exists(dirName) && fs::is_directory(dirName)) - { - GetLogger()->Error("Directory does not exist %s\n",dirName); - return false; - } - else - { - fs::remove_all(dirName); - } - - } - catch (std::exception & e) - { - GetLogger()->Error("Error on removing directory %s : %s\n", dirName, e.what()); - return false; - } - return true; -} - // Removes a player. void CMainDialog::NameDelete() { - CWindow* pw; - CList* pl; - int sel; - char* gamer; - char dir[100]; + CWindow* pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); + if (pw == nullptr) return; + CList* pl = static_cast(pw->SearchControl(EVENT_INTERFACE_NLIST)); + if (pl == nullptr) return; - pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); - if ( pw == 0 ) return; - pl = static_cast(pw->SearchControl(EVENT_INTERFACE_NLIST)); - if ( pl == 0 ) return; - - sel = pl->GetSelect(); - if ( sel == -1 ) + int sel = pl->GetSelect(); + if (sel == -1) { m_sound->Play(SOUND_TZOING); return; } - gamer = pl->GetItemName(sel); - // Deletes all the contents of the file. - sprintf(dir, "%s/%s", GetSavegameDir().c_str(), gamer); - if ( !RemoveDir(dir) ) + char* gamer = pl->GetItemName(sel); + + std::string userSaveDir = m_savegameDir + "/" + gamer; + if (!CResourceManager::RemoveDirectory(userSaveDir)) { m_sound->Play(SOUND_TZOING); return; @@ -3990,17 +3912,13 @@ void CMainDialog::DefPerso() bool CMainDialog::IsIOReadScene() { - fs::directory_iterator end_iter; - - fs::path saveDir(GetSavegameDir() + "/" + m_main->GetGamerName()); - if (fs::exists(saveDir) && fs::is_directory(saveDir)) + std::string userSaveDir = m_savegameDir + "/" + m_main->GetGamerName(); + auto saveDirs = CResourceManager::ListDirectories(userSaveDir); + for (auto dir : saveDirs) { - for( fs::directory_iterator dir_iter(saveDir) ; dir_iter != end_iter ; ++dir_iter) + if (CResourceManager::Exists(userSaveDir + "/" + dir + "/" + "data.sav")) { - if ( fs::is_directory(dir_iter->status()) && fs::exists(dir_iter->path() / "data.sav") ) - { - return true; - } + return true; } } @@ -4074,59 +3992,30 @@ void CMainDialog::IOReadName() void CMainDialog::IOReadList() { - FILE* file = NULL; - CWindow* pw; - CList* pl; - char line[500]; - char name[100]; - int i; - std::vector v; - - pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); - if ( pw == 0 ) return; - pl = static_cast(pw->SearchControl(EVENT_INTERFACE_IOLIST)); - if ( pl == 0 ) return; + CWindow* pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); + if (pw == nullptr) return; + CList* pl = static_cast(pw->SearchControl(EVENT_INTERFACE_IOLIST)); + if (pl == nullptr) return; pl->Flush(); - fs::path saveDir(GetSavegameDir() + "/" + m_main->GetGamerName()); m_saveList.clear(); - if (fs::exists(saveDir) && fs::is_directory(saveDir)) + std::string userSaveDir = m_savegameDir + "/" + m_main->GetGamerName(); + + auto saveDirs = CResourceManager::ListDirectories(userSaveDir); + std::sort(saveDirs.begin(), saveDirs.end()); + + for (auto dir : saveDirs) { - copy(fs::directory_iterator(saveDir), fs::directory_iterator(), back_inserter(v)); - std::sort(v.begin(), v.end()); - for( std::vector::iterator iter = v.begin(); iter != v.end(); ++iter) + std::string savegameFile = userSaveDir + "/" + dir + "/" + "data.sav"; + if (CResourceManager::Exists(savegameFile)) { - if ( fs::is_directory(*iter) && fs::exists(*iter / "data.sav") ) - { - - file = fopen((*iter / "data.sav").make_preferred().string().c_str(), "r"); - if ( file == NULL ) continue; - - while ( fgets(line, 500, file) != NULL ) - { - for ( i=0 ; i<500 ; i++ ) - { - if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space - if ( line[i] == '/' && line[i+1] == '/' ) - { - line[i] = 0; - break; - } - } - - if ( Cmd(line, "Title") ) - { - OpString(line, "text", name); - break; - } - } - fclose(file); - - pl->SetItemName(m_saveList.size(), name); - m_saveList.push_back(*iter); - } + CLevelParser* level = new CLevelParser(savegameFile); + level->Load(); + pl->SetItemName(m_saveList.size(), level->Get("Title")->GetParam("text")->AsString().c_str()); + m_saveList.push_back(userSaveDir + "/" + dir); + delete level; } } @@ -4165,12 +4054,7 @@ void CMainDialog::IOUpdateList() if (m_saveList.size() <= static_cast(sel)) return; - std::string filename = (m_saveList.at(sel) / "screen.png").make_preferred().string(); - std::string savedir = CResourceManager::GetSaveLocation()+"/"; - boost::replace_all(filename, "\\", "/"); - boost::replace_all(savedir, "\\", "/"); - boost::replace_all(filename, savedir, ""); //TODO: Refactor everything to PHYSFS, see issue #334 - filename = "../"+filename; + std::string filename = "../"+m_saveList.at(sel) + "/screen.png"; if ( m_phase == PHASE_WRITE || m_phase == PHASE_WRITEs ) { if ( sel < max-1 ) @@ -4214,16 +4098,9 @@ void CMainDialog::IODeleteScene() return; } - try + if (CResourceManager::DirectoryExists(m_saveList.at(sel))) { - if (fs::exists(m_saveList.at(sel)) && fs::is_directory(m_saveList.at(sel))) - { - fs::remove_all(m_saveList.at(sel)); - } - } - catch (std::exception & e) - { - GetLogger()->Error("Error removing save %s : %s\n", pl->GetItemName(sel), e.what()); + CResourceManager::RemoveDirectory(m_saveList.at(sel)); } IOReadList(); @@ -4267,28 +4144,28 @@ bool CMainDialog::IOWriteScene() return false; } - fs::path dir; + std::string dir; pe->GetText(info, 100); if (static_cast(sel) >= m_saveList.size()) { - dir = fs::path(GetSavegameDir()) / m_main->GetGamerName() / ("save" + clearName(info)); + dir = m_savegameDir + "/" + m_main->GetGamerName() + "/save" + clearName(info); } else { dir = m_saveList.at(sel); } - if (!fs::exists(dir)) + if (!CResourceManager::DirectoryExists(dir)) { - fs::create_directories(dir); + CResourceManager::CreateDirectory(dir); } - std::string fileName = (dir / "data.sav").make_preferred().string(); - std::string fileCBot = (dir / "cbot.run").make_preferred().string(); - m_main->IOWriteScene(fileName.c_str(), fileCBot.c_str(), info); + std::string savegameFileName = dir + "/data.sav"; + std::string fileCBot = CResourceManager::GetSaveLocation() + "/" + dir + "/cbot.run"; + m_main->IOWriteScene(savegameFileName.c_str(), fileCBot.c_str(), info); m_shotDelay = 3; - m_shotName = (dir / "screen.png").make_preferred().string(); + m_shotName = CResourceManager::GetSaveLocation() + "/" + dir + "/screen.png"; //TODO: Use PHYSFS? return true; } @@ -4297,11 +4174,8 @@ bool CMainDialog::IOWriteScene() bool CMainDialog::IOReadScene() { - FILE* file; CWindow* pw; CList* pl; - char line[500]; - char dir[100]; int sel, i; pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); @@ -4315,53 +4189,37 @@ bool CMainDialog::IOReadScene() return false; } - std::string fileName = (m_saveList.at(sel) / "data.sav").make_preferred().string(); - std::string fileCbot = (m_saveList.at(sel) / "cbot.run").make_preferred().string(); + std::string fileName = m_saveList.at(sel) + "/" + "data.sav"; + std::string fileCbot = CResourceManager::GetSaveLocation()+"/"+m_saveList.at(sel) + "/" + "cbot.run"; - file = fopen(fileName.c_str(), "r"); - if ( file == NULL ) + CLevelParser* level = new CLevelParser(fileName); + level->Load(); + + CLevelParserLine* line = level->Get("Mission"); + strcpy(m_sceneName, line->GetParam("base")->AsString().c_str()); + m_sceneRank = line->GetParam("rank")->AsInt(); + + if(std::string(m_sceneName) == "custom") { - return false; - } - - while ( fgets(line, 500, file) != NULL ) - { - for ( i=0 ; i<500 ; i++ ) + m_sceneRank = m_sceneRank%100; + + std::string dir = line->GetParam("dir")->AsString(); + for ( i=0 ; iAddParam("face", new CLevelParserParam(m_perso.face)); + line->AddParam("glasses", new CLevelParserParam(m_perso.glasses)); + line->AddParam("hair", new CLevelParserParam(m_perso.colorHair)); + perso->AddLine(line); + + line = new CLevelParserLine("Body"); + line->AddParam("combi", new CLevelParserParam(m_perso.colorCombi)); + line->AddParam("band", new CLevelParserParam(m_perso.colorBand)); + perso->AddLine(line); - sprintf(filename, "%s/%s/face.gam", GetSavegameDir().c_str(), gamer); - file = fopen(filename, "w"); - if ( file == NULL ) return; - - m_main->SetNumericLocale(); - - sprintf(line, "Head face=%d glasses=%d hair=%.2f;%.2f;%.2f;%.2f\n", - m_perso.face, m_perso.glasses, - m_perso.colorHair.r, m_perso.colorHair.g, m_perso.colorHair.b, m_perso.colorHair.a); - fputs(line, file); - - sprintf(line, "Body combi=%.2f;%.2f;%.2f;%.2f band=%.2f;%.2f;%.2f;%.2f\n", - m_perso.colorCombi.r, m_perso.colorCombi.g, m_perso.colorCombi.b, m_perso.colorCombi.a, - m_perso.colorBand.r, m_perso.colorBand.g, m_perso.colorBand.b, m_perso.colorBand.a); - fputs(line, file); - - fclose(file); - - m_main->RestoreNumericLocale(); + perso->Save(); + delete perso; + } catch(CLevelParserException& e) { + CLogger::GetInstancePointer()->Error("Unable to write personalized player apperance: %s\n", e.what()); + } } // Reads the personalized player. void CMainDialog::ReadGamerPerso(char *gamer) { - FILE* file; - char filename[100]; - char line[100]; - Gfx::Color color; - m_perso.face = 0; DefPerso(); + + if(!CResourceManager::Exists(GetSavegameDir()+"/"+gamer+"/face.gam")) + return; - sprintf(filename, "%s/%s/face.gam", GetSavegameDir().c_str(), gamer); - file = fopen(filename, "r"); - if ( file == NULL ) return; + try { + CLevelParser* perso = new CLevelParser(GetSavegameDir()+"/"+gamer+"/face.gam"); + perso->Load(); + CLevelParserLine* line; + + line = perso->Get("Head"); + m_perso.face = line->GetParam("face")->AsInt(); + m_perso.glasses = line->GetParam("glasses")->AsInt(); + m_perso.colorHair = line->GetParam("hair")->AsColor(); + + line = perso->Get("Body"); + m_perso.colorCombi = line->GetParam("combi")->AsColor(); + m_perso.colorBand = line->GetParam("band")->AsColor(); - m_main->SetNumericLocale(); - - while ( fgets(line, 100, file) != NULL ) - { - if ( Cmd(line, "Head") ) - { - m_perso.face = OpInt(line, "face", 0); - m_perso.glasses = OpInt(line, "glasses", 0); - - color.r = 0.0f; - color.g = 0.0f; - color.b = 0.0f; - color.a = 0.0f; - m_perso.colorHair = OpColor(line, "hair", color); - } - - if ( Cmd(line, "Body") ) - { - color.r = 0.0f; - color.g = 0.0f; - color.b = 0.0f; - color.a = 0.0f; - m_perso.colorCombi = OpColor(line, "combi", color); - - color.r = 0.0f; - color.g = 0.0f; - color.b = 0.0f; - color.a = 0.0f; - m_perso.colorBand = OpColor(line, "band", color); - } + delete perso; + } catch(CLevelParserException& e) { + CLogger::GetInstancePointer()->Error("Unable to read personalized player apperance: %s\n", e.what()); } - - fclose(file); - - m_main->RestoreNumericLocale(); } // Specifies the face of the player. @@ -6198,9 +6024,8 @@ Gfx::Color CMainDialog::GetGamerColorBand() bool CMainDialog::ReadGamerInfo() { - FILE* file; - char line[100]; - int chap, i, numTry, passed; + std::string line; + int chap, i, numTry, passed; for ( i=0 ; iGetGamerName(), m_sceneName); - file = fopen(line, "r"); - if ( file == NULL ) return false; - - if ( fgets(line, 100, file) != NULL ) - { - sscanf(line, "CurrentChapter=%d CurrentSel=%d\n", &chap, &i); - m_chap[m_index] = chap-1; - m_sel[m_index] = i-1; + if(!CResourceManager::Exists(GetSavegameDir()+"/"+m_main->GetGamerName()+"/"+m_sceneName+".gam")) + return false; + + CInputStream file; + file.open(GetSavegameDir()+"/"+m_main->GetGamerName()+"/"+m_sceneName+".gam"); + if(!file.is_open()) { + CLogger::GetInstancePointer()->Error("Unable to read list of finished missions\n"); + return false; } + + std::getline(file, line); + sscanf(line.c_str(), "CurrentChapter=%d CurrentSel=%d\n", &chap, &i); + m_chap[m_index] = chap-1; + m_sel[m_index] = i-1; - while ( fgets(line, 100, file) != NULL ) + while(!file.eof()) { - sscanf(line, "Chapter %d: Scene %d: numTry=%d passed=%d\n", + std::getline(file, line); + sscanf(line.c_str(), "Chapter %d: Scene %d: numTry=%d passed=%d\n", &chap, &i, &numTry, &passed); i += chap*100; @@ -6232,7 +6062,7 @@ bool CMainDialog::ReadGamerInfo() } } - fclose(file); + file.close(); return true; } @@ -6240,28 +6070,25 @@ bool CMainDialog::ReadGamerInfo() bool CMainDialog::WriteGamerInfo() { - FILE* file; - char line[100]; int i; - sprintf(line, "%s/%s/%s.gam", GetSavegameDir().c_str(), m_main->GetGamerName(), m_sceneName); - file = fopen(line, "w"); - if ( file == NULL ) return false; + COutputStream file; + file.open(GetSavegameDir()+"/"+m_main->GetGamerName()+"/"+m_sceneName+".gam"); + if(!file.is_open()) { + CLogger::GetInstancePointer()->Error("Unable to read list of finished missions\n"); + return false; + } - sprintf(line, "CurrentChapter=%d CurrentSel=%d\n", - m_chap[m_index]+1, m_sel[m_index]+1); - fputs(line, file); + file << "CurrentChapter=" << m_chap[m_index]+1 << " CurrentSel=" << m_sel[m_index]+1 << "\n"; for ( i=0 ; i -#include - #include -namespace fs = boost::filesystem; - class CEventQueue; class CSoundInterface; @@ -91,8 +86,7 @@ public: int GetSceneRank(); const char* GetSceneDir(); bool GetSceneSoluce(); - std::string GetSavegameDir(); - std::string & GetPHYSFSSavegameDir(); + std::string & GetSavegameDir(); std::string & GetPublicDir(); bool GetTooltip(); @@ -268,7 +262,7 @@ protected: SceneInfo m_sceneInfo[MAXSCENE]; - std::vector m_saveList; + std::vector m_saveList; }; } // namespace Ui diff --git a/src/ui/studio.cpp b/src/ui/studio.cpp index efdbbbc0..7198b910 100644 --- a/src/ui/studio.cpp +++ b/src/ui/studio.cpp @@ -1496,7 +1496,6 @@ void CStudio::UpdateDialogList() { CWindow* pw; CList* pl; - fs::path path; int i = 0; char time[100]; @@ -1506,52 +1505,38 @@ void CStudio::UpdateDialogList() if ( pl == nullptr ) return; pl->Flush(); - path = fs::path(SearchDirectory(false)); - fs::directory_iterator end_iter; - if ( fs::exists(path) && fs::is_directory(path) ) - { - for( fs::directory_iterator file(path); file != end_iter; file++) - { - if (fs::is_regular_file(file->status()) ) - { - std::ostringstream temp; - TimeToAscii(fs::last_write_time(file->path()), time); - temp << file->path().filename().string() << '\t' << fs::file_size(file->path()) << " \t" << time; - pl->SetItemName(i++, temp.str().c_str()); - } - } + if(!CResourceManager::DirectoryExists(SearchDirectory(false))) + return; + + std::vector programs = CResourceManager::ListFiles(SearchDirectory(false)); + for(auto& prog : programs) { + std::ostringstream temp; + TimeToAscii(CResourceManager::GetLastModificationTime(SearchDirectory(false) + prog), time); + temp << prog << '\t' << CResourceManager::GetFileSize(SearchDirectory(false) + prog) << " \t" << time; + pl->SetItemName(i++, temp.str().c_str()); } } // Constructs the name of the folder or open/save. // If the folder does not exist, it will be created. -//TODO: Refactor to PHYSFS -std::string CStudio::SearchDirectory(bool bCreate, bool physfsReady) +std::string CStudio::SearchDirectory(bool bCreate) { - char dir[MAX_FNAME]; + std::string dir; if ( m_main->GetIOPublic() ) { - sprintf(dir, "%s/", m_main->GetPublicDir()); + dir = std::string(m_main->GetPublicDir()) + "/"; } else { - sprintf(dir, "%s/%s/Program/", m_main->GetSavegameDir(), m_main->GetGamerName()); + dir = std::string(m_main->GetSavegameDir()) + "/" + std::string(m_main->GetGamerName()) + "/program/"; } if ( bCreate ) { - fs::path path = fs::path(dir); - fs::create_directories(path); + if(!CResourceManager::DirectoryExists(dir)) + CResourceManager::CreateDirectory(dir); } - - std::string dir2 = dir; - if(physfsReady) { - std::string savedir = CResourceManager::GetSaveLocation()+"/"; - boost::replace_all(dir2, "\\", "/"); - boost::replace_all(savedir, "\\", "/"); - boost::replace_all(dir2, savedir, ""); - } - return dir2; + return dir; } // Reads a new program. @@ -1577,7 +1562,7 @@ bool CStudio::ReadProgram() { strcat(filename, ".txt"); } - strcpy(dir, SearchDirectory(true, true).c_str()); + strcpy(dir, SearchDirectory(true).c_str()); strcat(dir, filename); pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW3)); @@ -1615,7 +1600,7 @@ bool CStudio::WriteProgram() { strcat(filename, ".txt"); } - strcpy(dir, SearchDirectory(true, true).c_str()); + strcpy(dir, SearchDirectory(true).c_str()); strcat(dir, filename); pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW3)); diff --git a/src/ui/studio.h b/src/ui/studio.h index dda1368c..a11d706c 100644 --- a/src/ui/studio.h +++ b/src/ui/studio.h @@ -88,7 +88,7 @@ protected: void UpdateDialogAction(); void UpdateDialogPublic(); void UpdateDialogList(); - std::string SearchDirectory(bool bCreate, bool physfsReady=false); + std::string SearchDirectory(bool bCreate); bool ReadProgram(); bool WriteProgram();