From de375548ade0015f6466fae74dc1fe9bba7c8357 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Fri, 26 Sep 2014 20:53:11 +0200 Subject: Userlevel listing --- src/object/level/parser.cpp | 31 +++++-- src/object/level/parserparam.cpp | 15 ++-- src/object/level/parserparam.h | 5 +- src/object/robotmain.cpp | 14 +-- src/object/robotmain.h | 2 +- src/ui/edit.cpp | 8 +- src/ui/maindialog.cpp | 189 +++++++-------------------------------- src/ui/maindialog.h | 4 +- 8 files changed, 81 insertions(+), 187 deletions(-) diff --git a/src/object/level/parser.cpp b/src/object/level/parser.cpp index 89059d0..e73142e 100644 --- a/src/object/level/parser.cpp +++ b/src/object/level/parser.cpp @@ -23,6 +23,8 @@ #include "object/level/parserexceptions.h" +#include "object/robotmain.h" + #include #include #include @@ -57,12 +59,25 @@ CLevelParser::~CLevelParser() std::string CLevelParser::BuildSceneName(std::string category, int chapter, int rank, bool sceneFile) { std::ostringstream outstream; - if(category == "user") + if(category == "custom") { - //TODO: Change this to point user dir according to operating system - /*rankStream << std::setfill('0') << std::setw(2) << rank%100; - filename = m_userDir + "/" + m_userList[rank/100-1] + "/" + rankStream.str() + ".txt";*/ - assert(false); //TODO: Userlevel support + outstream << "levels/custom/"; + outstream << CRobotMain::GetInstancePointer()->GetUserLevelName(chapter) << "/"; + if(rank == 000) + { + if(sceneFile) + { + outstream << "/chaptertitle.txt"; + } + } + else + { + outstream << "/level" << std::setfill('0') << std::setw(3) << rank; + if(sceneFile) + { + outstream << "/scene.txt"; + } + } } else if(category == "perso") { @@ -217,5 +232,9 @@ void CLevelParser::AddLine(CLevelParserLine* line) CLevelParserLine* CLevelParser::Get(std::string command) { - assert(false); //TODO + for(auto& line : m_lines) { + if(line->GetCommand() == command) + return line; + } + throw CLevelParserException("Command not found: "+command); } \ No newline at end of file diff --git a/src/object/level/parserparam.cpp b/src/object/level/parserparam.cpp index ec043b4..39a953b 100644 --- a/src/object/level/parserparam.cpp +++ b/src/object/level/parserparam.cpp @@ -168,9 +168,6 @@ std::string CLevelParserParam::InjectLevelDir(std::string path, const std::strin if(newPath == path) { newPath = defaultDir + (!defaultDir.empty() ? "/" : "") + newPath; - } else { - if(defaultDir == "") - throw CLevelParserException("TODO: Param "+m_name+" does not yet support %lvl%! :("); } //TODO: Fallback to English std::string langStr(1, CApplication::GetInstancePointer()->GetLanguageChar()); @@ -178,12 +175,20 @@ std::string CLevelParserParam::InjectLevelDir(std::string path, const std::strin return newPath; } +std::string CLevelParserParam::ToPath(std::string path, const std::string defaultDir) +{ + if(defaultDir == "" && path.find("%lvl%") != std::string::npos) + throw CLevelParserException("TODO: Param "+m_name+" does not yet support %lvl%! :("); + + return InjectLevelDir(path, defaultDir); +} + std::string CLevelParserParam::AsPath(const std::string defaultDir) { if(m_empty) throw CLevelParserExceptionMissingParam(this); - return InjectLevelDir(AsString(), defaultDir); + return ToPath(AsString(), defaultDir); } std::string CLevelParserParam::AsPath(const std::string defaultDir, std::string def) @@ -191,7 +196,7 @@ std::string CLevelParserParam::AsPath(const std::string defaultDir, std::string if(m_empty) return InjectLevelDir(def, defaultDir); - return InjectLevelDir(AsString(def), defaultDir); + return ToPath(AsString(def), defaultDir); } diff --git a/src/object/level/parserparam.h b/src/object/level/parserparam.h index 9d5ba99..93865a2 100644 --- a/src/object/level/parserparam.h +++ b/src/object/level/parserparam.h @@ -103,14 +103,15 @@ public: std::string GetValue(); bool IsDefined(); + static std::string InjectLevelDir(std::string path, const std::string defaultDir); + private: void ParseArray(); template T Cast(std::string value, std::string requestedType); template T Cast(std::string requestedType); - std::string InjectLevelDir(std::string path, const std::string defaultDir); - + std::string ToPath(std::string path, const std::string defaultDir); ObjectType ToObjectType(std::string value); DriveType ToDriveType(std::string value); ToolType ToToolType(std::string value); diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp index ce7f8d0..315ffe1 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -3874,7 +3874,6 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) int rank = m_dialog->GetSceneRank(); const char* read = m_dialog->GetSceneRead().c_str(); const char* stack = m_dialog->GetStackRead().c_str(); - m_dialog->SetUserDir(base, rank); m_fixScene = fixScene; @@ -7137,16 +7136,7 @@ void CRobotMain::DisplayError(Error err, Math::Vector goal, float height, float m_displayText->DisplayError(err, goal, height, dist, time); } -void CRobotMain::InjectLevelDir(std::string& path, const std::string defaultDir) +std::string& CRobotMain::GetUserLevelName(int id) { - std::string oldPath = path; - std::string lvlDir; - CRobotMain::GetInstancePointer()->BuildSceneName(lvlDir, CRobotMain::GetInstancePointer()->GetSceneName(), CRobotMain::GetInstancePointer()->GetSceneRank(), false); - boost::replace_all(path, "%lvl%", lvlDir); - if(path == oldPath) - { - path = defaultDir + "/" + path; - } - std::string langStr(1, CApplication::GetInstancePointer()->GetLanguageChar()); - boost::replace_all(path, "%lng%", langStr); + return m_dialog->GetUserLevelName(id); } diff --git a/src/object/robotmain.h b/src/object/robotmain.h index f9bf131..466c47d 100644 --- a/src/object/robotmain.h +++ b/src/object/robotmain.h @@ -390,7 +390,7 @@ public: void DisplayError(Error err, CObject* pObj, float time=10.0f); void DisplayError(Error err, Math::Vector goal, float height=15.0f, float dist=60.0f, float time=10.0f); - static void InjectLevelDir(std::string& path, const std::string defaultDir = ""); + std::string& GetUserLevelName(int id); protected: bool EventFrame(const Event &event); diff --git a/src/ui/edit.cpp b/src/ui/edit.cpp index 8f46e42..68c503b 100644 --- a/src/ui/edit.cpp +++ b/src/ui/edit.cpp @@ -24,6 +24,8 @@ #include "object/robotmain.h" +#include "object/level/parserparam.h" + #include "common/resources/inputstream.h" #include "common/resources/outputstream.h" @@ -788,7 +790,7 @@ void CEdit::HyperJump(std::string name, std::string marker) sMarker = marker; filename = name + std::string(".txt"); - CRobotMain::InjectLevelDir(filename, "help/%lng%"); + filename = CLevelParserParam::InjectLevelDir(filename, "help/%lng%"); boost::replace_all(filename, "\\", "/"); //TODO: Fix this in files if ( ReadText(filename) ) @@ -1144,7 +1146,7 @@ void CEdit::DrawImage(Math::Point pos, std::string name, float width, std::string filename; filename = name + ".png"; - CRobotMain::InjectLevelDir(filename, "icons"); + filename = CLevelParserParam::InjectLevelDir(filename, "icons"); boost::replace_all(filename, "\\", "/"); //TODO: Fix this in files m_engine->SetTexture(filename); @@ -1434,7 +1436,7 @@ void CEdit::LoadImage(std::string name) { std::string filename; filename = name + ".png"; - CRobotMain::InjectLevelDir(filename, "icons"); + filename = CLevelParserParam::InjectLevelDir(filename, "icons"); boost::replace_all(filename, "\\", "/"); //TODO: Fix this in files m_engine->LoadTexture(filename); } diff --git a/src/ui/maindialog.cpp b/src/ui/maindialog.cpp index 068732d..3acf1dd 100644 --- a/src/ui/maindialog.cpp +++ b/src/ui/maindialog.cpp @@ -33,6 +33,8 @@ #include "common/resources/inputstream.h" #include "common/resources/outputstream.h" +#include "object/level/parser.h" + #include "object/robotmain.h" #include "script/cmdtoken.h" @@ -52,7 +54,6 @@ #include "ui/window.h" #include "ui/edit.h" #include "ui/editvalue.h" -#include #include #include @@ -177,14 +178,8 @@ CMainDialog::CMainDialog() m_partiTime[i] = 0.0f; } - #if DEV_BUILD - m_savegameDir = "savegame"; - #else m_savegameDir = "savegame"; - #endif - m_publicDir = "program"; - m_userDir = "user"; m_filesDir = m_savegameDir; m_setupFull = m_app->GetVideoConfig().fullScreen; @@ -316,7 +311,6 @@ void CMainDialog::ChangePhase(Phase phase) pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_QUIT); pb->SetState(STATE_SHADOW); - #if DEV_BUILD if ( m_accessEnable && m_accessUser ) { pos.x = 447.0f/640.0f; @@ -325,7 +319,6 @@ void CMainDialog::ChangePhase(Phase phase) pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_USER); pb->SetState(STATE_SHADOW); } - #endif /*pos.x = 139.0f/640.0f; pos.y = 313.0f/480.0f; @@ -723,7 +716,7 @@ void CMainDialog::ChangePhase(Phase phase) if ( m_phase == PHASE_DEFI ) strcpy(m_sceneName, "challenges" ); if ( m_phase == PHASE_MISSION ) strcpy(m_sceneName, "missions"); if ( m_phase == PHASE_FREE ) strcpy(m_sceneName, "freemissions"); - if ( m_phase == PHASE_USER ) strcpy(m_sceneName, "user"); + if ( m_phase == PHASE_USER ) strcpy(m_sceneName, "custom"); ReadGamerInfo(); @@ -3271,23 +3264,6 @@ void CMainDialog::NiceParticle(Math::Point mouse, bool bPress) -// Specifies the special user folder if needed. - -void CMainDialog::SetUserDir(char *base, int rank) -{ - std::string dir; - - if ( strcmp(base, "user") == 0 && rank >= 100 ) - { - dir = m_userDir + "/" + m_userList.at(rank/100-1); - GetProfile().SetUserDir(dir); - } - else - { - GetProfile().SetUserDir(""); - } -} - // Builds the file name of a mission. void CMainDialog::BuildSceneName(std::string &filename, char *base, int rank, bool sceneFile) @@ -3296,45 +3272,7 @@ void CMainDialog::BuildSceneName(std::string &filename, char *base, int rank, bo int chapter = rank/100; int new_rank = rank%100; - std::ostringstream outstream; - if ( strcmp(base, "user") == 0 ) - { - //TODO: Change this to point user dir according to operating system - /*rankStream << std::setfill('0') << std::setw(2) << rank%100; - filename = m_userDir + "/" + m_userList[rank/100-1] + "/" + rankStream.str() + ".txt";*/ - assert(false); //TODO: Userlevel support - } - else if ( strcmp(base, "perso") == 0 ) - { - filename = "levels/other/perso.txt"; - } - else if( strcmp(base, "win") == 0 || strcmp(base, "lost") == 0 ) - { - outstream << "levels/other/"; - outstream << base << std::setfill('0') << std::setw(3) << rank << ".txt"; - filename = outstream.str(); - } - else - { - outstream << "levels/" << base << "/"; - outstream << "chapter" << std::setfill('0') << std::setw(3) << chapter << "/"; - if(new_rank == 000) - { - if(sceneFile) - { - outstream << "chaptertitle.txt"; - } - } - else - { - outstream << "level" << std::setfill('0') << std::setw(3) << new_rank << "/"; - if(sceneFile) - { - outstream << "scene.txt"; - } - } - filename = outstream.str(); - } + filename = CLevelParser::BuildSceneName(std::string(base), chapter, new_rank, sceneFile); } // Built the default descriptive name of a mission. @@ -4423,7 +4361,6 @@ void CMainDialog::UpdateSceneChap(int &chap) { CWindow* pw; CList* pl; - FILE *file; std::string fileName; char op[100]; @@ -4448,60 +4385,25 @@ void CMainDialog::UpdateSceneChap(int &chap) if ( m_phase == PHASE_USER ) { j = 0; - fs::directory_iterator dirIt(m_savegameDir), dirEndIt; - m_userList.clear(); - - for (; dirIt != dirEndIt; ++dirIt) - { - const fs::path& p = *dirIt; - if (fs::is_directory(p)) - { - m_userList.push_back(p.leaf().string()); - } - } + auto userLevelDirs = CResourceManager::ListDirectories("levels/custom/"); + std::sort(userLevelDirs.begin(), userLevelDirs.end()); + m_userList = userLevelDirs; m_userTotal = m_userList.size(); for ( j=0 ; jLoad(); + pl->SetItemName(j, level->Get("Title")->GetParam("text")->AsString().c_str()); + pl->SetEnable(j, true); + delete level; } - else + catch(CLevelParserException& e) { - BuildResumeName(name, m_sceneName, j+1); // default name - sprintf(op, "Title.E"); - sprintf(op_i18n, "Title.%c", m_app->GetLanguageChar()); - - 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, op) ) - { - OpString(line, "text", name); - } - if ( Cmd(line, op_i18n) ) - { - OpString(line, "text", name); - break; - } - } - fclose(file); + pl->SetItemName(j, (std::string("[ERROR]: ")+e.what()).c_str()); + pl->SetEnable(j, false); } - - pl->SetItemName(j, name); - pl->SetEnable(j, true); } } else @@ -4592,6 +4494,8 @@ void CMainDialog::UpdateSceneList(int chap, int &sel) if ( pl == 0 ) return; pl->Flush(); + + if(chap < 0) return; for ( j=0 ; j<99 ; j++ ) { @@ -4738,44 +4642,18 @@ void CMainDialog::UpdateSceneResume(int rank) m_bSceneSoluce = false; } } - - BuildSceneName(fileName, m_sceneName, rank); - sprintf(op, "Resume.E"); - sprintf(op_i18n, "Resume.%c", m_app->GetLanguageChar()); - - CInputStream stream; - stream.open(fileName); - if (!stream.is_open()) return; - - name[0] = 0; - while ( stream.getline(line, 500) ) + + if(rank<100) return; + + try { + CLevelParser* level = new CLevelParser(m_sceneName, rank/100, rank%100); + level->Load(); + pe->SetText(level->Get("Resume")->GetParam("text")->AsString().c_str()); + } + catch(CLevelParserException& e) { - for ( i=0 ; i<500 ; i++ ) - { - if (line[i] == 0) - break; - - if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space - if ( line[i] == '/' && line[i+1] == '/' ) - { - line[i] = 0; - break; - } - } - - if ( Cmd(line, op) ) - { - OpString(line, "text", name); - } - if ( Cmd(line, op_i18n) ) - { - OpString(line, "text", name); - break; - } + pe->SetText((std::string("[ERROR]: ")+e.what()).c_str()); } - stream.close(); - - pe->SetText(name); } // Updates the list of devices. @@ -5202,7 +5080,6 @@ void CMainDialog::SetupMemorize() { GetProfile().SetLocalProfileString("Directory", "savegame", m_savegameDir); GetProfile().SetLocalProfileString("Directory", "public", m_publicDir); - GetProfile().SetLocalProfileString("Directory", "user", m_userDir); GetProfile().SetLocalProfileString("Directory", "files", m_filesDir); GetProfile().SetLocalProfileInt("Setup", "Tooltips", m_bTooltip); GetProfile().SetLocalProfileInt("Setup", "InterfaceGlint", m_bGlint); @@ -5288,11 +5165,6 @@ void CMainDialog::SetupRecall() m_publicDir = key; } - if ( GetProfile().GetLocalProfileString("Directory", "user", key) ) - { - m_userDir = key; - } - if ( GetProfile().GetLocalProfileString("Directory", "files", key) ) { m_filesDir = key; @@ -6487,6 +6359,11 @@ bool CMainDialog::NextMission() return true; } +std::string& CMainDialog::GetUserLevelName(int id) +{ + return m_userList[id-1]; +} + } // namespace Ui diff --git a/src/ui/maindialog.h b/src/ui/maindialog.h index cb26426..2b3ca6f 100644 --- a/src/ui/maindialog.h +++ b/src/ui/maindialog.h @@ -98,7 +98,6 @@ public: bool GetNiceReset(); bool GetHimselfDamage(); - void SetUserDir(char *base, int rank); void BuildSceneName(std::string &filename, char *base, int rank, bool sceneFile = true); void BuildResumeName(char *filename, char *base, int rank); std::string & GetFilesDir(); @@ -140,6 +139,8 @@ public: void AllMissionUpdate(); void ShowSoluceUpdate(); + + std::string& GetUserLevelName(int id); protected: void GlintMove(); @@ -202,7 +203,6 @@ protected: std::string m_savegameDir; // savegame folder std::string m_publicDir; // program folder - std::string m_userDir; // user folder std::string m_filesDir; // case files int m_index; // 0..4 -- cgit v1.2.3-1-g7c22