]> git.jsancho.org Git - lugaru.git/commitdiff
Console: Return gracefully when loading missing level
authorRémi Verschelde <rverschelde@gmail.com>
Wed, 4 Jan 2017 17:28:04 +0000 (18:28 +0100)
committerRémi Verschelde <rverschelde@gmail.com>
Wed, 4 Jan 2017 17:39:47 +0000 (18:39 +0100)
For this, implemented Folders::file_exists to check for the existence
of a given file, so that we can exit gracefully before raising a FileNotFound
exception which then closes the game.

The console and stderr both display an error message.
Part of #23.

Source/Devtools/ConsoleCmds.cpp
Source/Game.hpp
Source/GameTick.cpp
Source/Menu/Menu.cpp
Source/Utils/Folders.cpp
Source/Utils/Folders.hpp

index b9aabcc4dd812757d221d5272bf7deed4c9259d4..b11e12a7fb528b2b43e9ac62bf56fe3572afa239 100644 (file)
@@ -163,7 +163,14 @@ void ch_quit(const char *)
 
 void ch_map(const char *args)
 {
-    Loadlevel(args);
+    if (!LoadLevel(args)) {
+        // FIXME: Reduce code duplication with GameTick (should come from a Console class)
+        for (int k = 14; k >= 1; k--) {
+            consoletext[k] = consoletext[k - 1];
+        }
+        consoletext[0] = std::string("Could not load the requested level '") + args + "', aborting.";
+        consoleselected = 0;
+    }
     whichlevel = -2;
     campaign = 0;
 }
index 17e188ab019bf2182cf06983746811cdc8f6b9e2..159cbe78fc3c5dfdbf508a0093500f92990175c1 100644 (file)
@@ -144,8 +144,8 @@ void LoadingScreen();
 int DrawGLScene(StereoSide side);
 void playdialoguescenesound();
 int findClosestPlayer();
-void Loadlevel(int which);
-void Loadlevel(const std::string& name, bool tutorial = false);
+bool LoadLevel(int which);
+bool LoadLevel(const std::string& name, bool tutorial = false);
 void Tick();
 void TickOnce();
 void TickOnceAfter();
index ed22ee26b33e57f299ee51cd61f5c9fc450b8013..58fb64aac4fd7a467e01cbb9cf14ce390c7a4ee5 100644 (file)
@@ -491,24 +491,30 @@ void Setenvironment(int which)
     texdetail = temptexdetail;
 }
 
-void Game::Loadlevel(int which)
+bool Game::LoadLevel(int which)
 {
     stealthloading = 0;
     whichlevel = which;
 
     if (which == -1) {
-        Loadlevel("tutorial", true);
+        return LoadLevel("tutorial", true);
     } else if (which >= 0 && which <= 15) {
         char buf[32];
         snprintf(buf, 32, "map%d", which + 1); // challenges
-        Loadlevel(buf);
+        return LoadLevel(buf);
     } else {
-        Loadlevel("mapsave");
+        return LoadLevel("mapsave");
     }
 }
 
-void Game::Loadlevel(const std::string& name, bool tutorial)
+bool Game::LoadLevel(const std::string& name, bool tutorial)
 {
+    const std::string level_path = Folders::getResourcePath("Maps/" + name);
+    if (!Folders::file_exists(level_path)) {
+        perror(std::string("LoadLevel: Could not open file '" + level_path).c_str());
+        return false;
+    }
+
     int indemo; // FIXME this should be removed
     int templength;
     float lamefloat;
@@ -542,7 +548,7 @@ void Game::Loadlevel(const std::string& name, bool tutorial)
     int mapvers;
     FILE *tfile;
     errno = 0;
-    tfile = Folders::openMandatoryFile( Folders::getResourcePath("Maps/"+name), "rb" );
+    tfile = Folders::openMandatoryFile(level_path, "rb");
 
     pause_sound(stream_firesound);
     scoreadded = 0;
@@ -929,6 +935,8 @@ void Game::Loadlevel(const std::string& name, bool tutorial)
     leveltime = 0;
     wonleveltime = 0;
     visibleloading = false;
+
+    return true;
 }
 
 void doDevKeys()
@@ -4484,11 +4492,8 @@ void Game::TickOnceAfter()
 
                     if (!Person::players[0]->dead && targetlevel != whichlevel)
                         startbonustotal = bonustotal;
-                    if (Person::players[0]->dead)
-                        Loadlevel(whichlevel);
-                    else
-                        Loadlevel(targetlevel);
 
+                    LoadLevel(targetlevel);
                     fireSound();
 
                     loading = 3;
@@ -4499,7 +4504,7 @@ void Game::TickOnceAfter()
 
                     fireSound(firestartsound);
 
-                    Loadlevel(campaignlevels[Account::active().getCampaignChoicesMade()].mapname.c_str());
+                    LoadLevel(campaignlevels[Account::active().getCampaignChoicesMade()].mapname.c_str());
 
                     fireSound();
 
@@ -4559,7 +4564,7 @@ void Game::TickOnceAfter()
                     actuallevel = campaignlevels[actuallevel].nextlevel.front();
                     visibleloading = true;
                     stillloading = 1;
-                    Loadlevel(campaignlevels[actuallevel].mapname.c_str());
+                    LoadLevel(campaignlevels[actuallevel].mapname.c_str());
                     campaign = 1;
                     mainmenu = 0;
                     gameon = 1;
index 27582aad5d9c4fa7bee5e194f15c262528fb9094..91dd2ed7efa6c0336062989809d964ccb38c5691 100644 (file)
@@ -715,7 +715,7 @@ void Menu::Tick()
                 actuallevel = (Account::active().getCampaignChoicesMade() > 0 ? campaignlevels[Account::active().getCampaignChoicesMade() - 1].nextlevel[whichchoice] : 0);
                 visibleloading = true;
                 stillloading = 1;
-                Loadlevel(campaignlevels[actuallevel].mapname.c_str());
+                LoadLevel(campaignlevels[actuallevel].mapname.c_str());
                 campaign = 1;
                 mainmenu = 0;
                 gameon = 1;
@@ -733,7 +733,7 @@ void Menu::Tick()
                 } else {
                     LoadStuff();
                 }
-                Loadlevel(-1);
+                LoadLevel(-1);
 
                 mainmenu = 0;
                 gameon = 1;
@@ -820,7 +820,7 @@ void Menu::Tick()
                 } else {
                     LoadStuff();
                 }
-                Loadlevel(selected);
+                LoadLevel(selected);
                 campaign = 0;
 
                 mainmenu = 0;
index 8f2bc18feddfc1c2b44af47ac1adbc5592240448..3fa04025823b3502f4959ebc50e8a5fb83d6b57f 100644 (file)
@@ -133,3 +133,15 @@ FILE* Folders::openMandatoryFile(const std::string& filename, const char* mode)
     }
     return tfile;
 }
+
+bool Folders::file_exists(const std::string& filepath)
+{
+    FILE* file;
+    file = fopen(filepath.c_str(), "rb");
+    if (file == NULL) {
+        return false;
+    } else {
+        fclose(file);
+        return true;
+    }
+}
index 9ecf9e0219eb47395c0d2ea449ed4b3abcbcc48a..d812d10295db6fcc8b05785002e253d7306af48a 100644 (file)
@@ -56,6 +56,8 @@ public:
 
     static FILE* openMandatoryFile(const std::string& filename, const char* mode);
 
+    static bool file_exists(const std::string& filepath);
+
     /* Returns full path for a game resource */
     static inline std::string getResourcePath(const std::string& filepath)
     { return dataDir + '/' + filepath; }