Map deletion button
authorPerttu Ahola <celeron55@gmail.com>
Tue, 25 Jan 2011 22:40:33 +0000 (00:40 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Tue, 25 Jan 2011 22:40:33 +0000 (00:40 +0200)
src/filesys.cpp
src/filesys.h
src/guiMainMenu.cpp
src/guiMainMenu.h
src/main.cpp

index a2d3f9d145c2388da2db27ca7aa2c298f704c15f..a025ec18562872392cedcdf3968f542d3754236c 100644 (file)
@@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "filesys.h"
 #include <iostream>
+#include <string.h>
 
 namespace fs
 {
@@ -130,12 +131,35 @@ bool PathExists(std::string path)
        return (GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES);
 }
 
+bool RecursiveDelete(std::string path)
+{
+       std::cerr<<"Removing \""<<path<<"\""<<std::endl;
+
+       return false;
+       
+       // This silly function needs a double-null terminated string...
+       // Well, we'll just make sure it has at least two, then.
+       path += "\0\0";
+
+       SHFILEOPSTRUCT sfo;
+       sfo.hwnd = NULL;
+       sfo.wFunc = FO_DELETE;
+       sfo.pFrom = path.c_str();
+       sfo.pTo = NULL;
+       sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR;
+       
+       int r = SHFileOperation(&sfo);
+
+       return (r == 0);
+}
+
 #else // POSIX
 
 #include <sys/types.h>
 #include <dirent.h>
 #include <errno.h>
 #include <sys/stat.h>
+#include <sys/wait.h>
 
 std::vector<DirListNode> GetDirListing(std::string pathstring)
 {
@@ -184,7 +208,70 @@ bool PathExists(std::string path)
        return (stat(path.c_str(),&st) == 0);
 }
 
+bool RecursiveDelete(std::string path)
+{
+       /*
+               Execute the 'rm' command directly, by fork() and execve()
+       */
+       
+       std::cerr<<"Removing \""<<path<<"\""<<std::endl;
+
+       //return false;
+       
+       pid_t child_pid = fork();
+
+       if(child_pid == 0)
+       {
+               // Child
+               char argv_data[3][10000];
+               strcpy(argv_data[0], "/bin/rm");
+               strcpy(argv_data[1], "-rf");
+               strncpy(argv_data[2], path.c_str(), 10000);
+               char *argv[4];
+               argv[0] = argv_data[0];
+               argv[1] = argv_data[1];
+               argv[2] = argv_data[2];
+               argv[3] = NULL;
+
+               std::cerr<<"Executing '"<<argv[0]<<"' '"<<argv[1]<<"' '"
+                               <<argv[2]<<"'"<<std::endl;
+               
+               execv(argv[0], argv);
+               
+               // Execv shouldn't return. Failed.
+               return false;
+       }
+       else
+       {
+               // Parent
+               int child_status;
+               pid_t tpid;
+               do{
+                       tpid = wait(&child_status);
+                       //if(tpid != child_pid) process_terminated(tpid);
+               }while(tpid != child_pid);
+               return (child_status == 0);
+       }
+}
+
 #endif
 
+bool RecursiveDeleteContent(std::string path)
+{
+       std::cerr<<"Removing content of \""<<path<<"\""<<std::endl;
+       std::vector<DirListNode> list = GetDirListing(path);
+       for(unsigned int i=0; i<list.size(); i++)
+       {
+               std::string childpath = path+"/"+list[i].name;
+               bool r = RecursiveDelete(childpath);
+               if(r == false)
+               {
+                       std::cerr<<"Removing \""<<childpath<<"\" failed"<<std::endl;
+                       return false;
+               }
+       }
+       return true;
+}
+
 } // namespace fs
 
index 6dbc426a5494454a075047300808e77071eb86b7..e46b17b0def460faace60aa16759a1004890be54 100644 (file)
@@ -40,6 +40,12 @@ bool CreateDir(std::string path);
 
 bool PathExists(std::string path);
 
+// Only pass full paths to this one. True on success.
+bool RecursiveDelete(std::string path);
+
+// Only pass full paths to this one. True on success.
+bool RecursiveDeleteContent(std::string path);
+
 }//fs
 
 #endif
index 84435b5f34fb797f8fcc99b3512dd9972cdc849a..2d02c0295f1238a9c56c95aa1956840fde0495e5 100644 (file)
@@ -177,6 +177,12 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
                rect = rect + v2s32(size.X/2-180/2, size.Y/2-30/2 + 100);
                Environment->addButton(rect, this, 257, L"Start Game / Connect");
        }
+       // Map delete button
+       {
+               core::rect<s32> rect(0, 0, 130, 30);
+               rect = rect + v2s32(size.X/2-130/2+200, size.Y/2-30/2 + 100);
+               Environment->addButton(rect, this, 260, L"Delete map");
+       }
 }
 
 void GUIMainMenu::drawMenu()
@@ -252,10 +258,16 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
                {
                        switch(event.GUIEvent.Caller->getID())
                        {
-                       case 257:
+                       case 257: // Start game
                                acceptInput();
                                quitMenu();
                                break;
+                       case 260: // Delete map
+                               // Don't accept input data, just set deletion request
+                               m_data->delete_map = true;
+                               m_accepted = true;
+                               quitMenu();
+                               break;
                        }
                }
                if(event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER)
index 8060f511d75a6ebf61f71a1e3cf306a0ab92f51d..010d0bf6d975e71dc27b2c29d1bd7e69a39226c9 100644 (file)
@@ -29,11 +29,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 struct MainMenuData
 {
+       MainMenuData():
+               creative_mode(false),
+               delete_map(false)
+       {}
        // These are in the native format of the gui elements
        std::wstring address;
        std::wstring port;
        std::wstring name;
        bool creative_mode;
+       // If map deletion is requested, this is set to true
+       bool delete_map;
 };
 
 class GUIMainMenu : public GUIModalMenu
index 171f1538a6f3e0e221b8c1c9d12607304dc2e3a1..da1b88d4a9db3220f865a57beb409000251f22f8 100644 (file)
@@ -153,8 +153,10 @@ TODO: Optimize day/night mesh updating somehow
                   meshbuffers? It should go quite fast.\r
                   - This is not easy; There'd need to be a buffer somewhere\r
                     that would contain the night and day lighting values.\r
+                        - Actually if FastFaces would be stored, they could\r
+                          hold both values\r
 \r
-TODO: Combine MapBlock's face caches to so big pieces that VBO\r
+FEATURE: Combine MapBlock's face caches to so big pieces that VBO\r
       gets used\r
       - That is >500 vertices\r
          - This is not easy; all the MapBlocks close to the player would\r
@@ -181,6 +183,10 @@ TODO: Untie client network operations from framerate
 \r
 TODO: Make morning and evening shorter\r
 \r
+TODO: Don't update all meshes always on single node changes, but\r
+      check which ones should be updated\r
+         - implement Map::updateNodeMeshes()\r
+\r
 Server:\r
 -------\r
 \r
@@ -260,10 +266,15 @@ FEATURE: The map could be generated procedually:
                - How about relocating minerals, too? Coal and gold in\r
                  downstream sand and gravel would be kind of cool\r
                  - This would need a better way of handling minerals, mainly\r
-                   to have mineral content as a separate field\r
+                   to have mineral content as a separate field. the first\r
+                       parameter field is free for this.\r
                - Simulate rock falling from cliffs when water has removed\r
                  enough solid rock from the bottom\r
 \r
+TODO: Mineral and ground material properties\r
+      - This way mineral ground toughness can be calculated with just\r
+           some formula, as well as tool strengths\r
+\r
 TODO: Change AttributeList to split the area into smaller sections so\r
       that searching won't be as heavy.\r
 \r
@@ -308,6 +319,7 @@ Doing now:
 #pragma comment(lib, "Irrlicht.lib")\r
 //#pragma comment(lib, "jthread.lib")\r
 #pragma comment(lib, "zlibwapi.lib")\r
+#pragma comment(lib, "Shell32.lib")\r
 // This would get rid of the console window\r
 //#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")\r
 #endif\r
@@ -1270,9 +1282,12 @@ int main(int argc, char *argv[])
        porting::initializePaths();\r
        // Create user data directory\r
        fs::CreateDir(porting::path_userdata);\r
-\r
+       \r
+       // C-style stuff initialization\r
        initializeMaterialProperties();\r
+       init_mapnode();\r
 \r
+       // Debug handler\r
        BEGIN_DEBUG_EXCEPTION_HANDLER\r
 \r
        // Print startup message\r
@@ -1550,7 +1565,7 @@ int main(int argc, char *argv[])
        */\r
 \r
        init_content_inventory_texture_paths();\r
-       init_tile_textures();\r
+       //init_tile_textures();\r
 \r
        /*\r
                GUI stuff\r
@@ -1608,10 +1623,10 @@ int main(int argc, char *argv[])
        {\r
        \r
        /*\r
-               Out-of-game menu loop\r
+               Out-of-game menu loop.\r
+\r
+               Loop quits when menu returns proper parameters.\r
        */\r
-       \r
-       // Wait for proper parameters\r
        for(;;)\r
        {\r
                // Cursor can be non-visible when coming from the game\r
@@ -1671,6 +1686,15 @@ int main(int argc, char *argv[])
                dstream<<"Dropping main menu"<<std::endl;\r
 \r
                menu->drop();\r
+               \r
+               // Delete map if requested\r
+               if(menudata.delete_map)\r
+               {\r
+                       bool r = fs::RecursiveDeleteContent(map_dir);\r
+                       if(r == false)\r
+                               error_message = L"Delete failed";\r
+                       continue;\r
+               }\r
 \r
                playername = wide_to_narrow(menudata.name);\r
                address = wide_to_narrow(menudata.address);\r
@@ -2386,8 +2410,20 @@ int main(int argc, char *argv[])
 \r
                        static float dig_time = 0.0;\r
                        static u16 dig_index = 0;\r
+                       \r
+                       // Visualize selection\r
+\r
+                       const float d = 0.502;\r
+                       core::aabbox3d<f32> nodebox(-BS*d, -BS*d, -BS*d, BS*d, BS*d, BS*d);\r
+                       v3f nodepos_f = intToFloat(nodepos);\r
+                       //v3f nodepos_f(nodepos.X*BS, nodepos.Y*BS, nodepos.Z*BS);\r
+                       nodebox.MinEdge += nodepos_f;\r
+                       nodebox.MaxEdge += nodepos_f;\r
+                       hilightboxes.push_back(nodebox);\r
+                       \r
+                       //hilightboxes.push_back(nodefacebox);\r
 \r
-                       hilightboxes.push_back(nodefacebox);\r
+                       // Handle digging\r
                        \r
                        if(g_input->getLeftReleased())\r
                        {\r
@@ -2473,6 +2509,7 @@ int main(int argc, char *argv[])
 \r
                                        if(dig_index < CRACK_ANIMATION_LENGTH)\r
                                        {\r
+                                               //TimeTaker timer("client.setTempMod");\r
                                                //dstream<<"dig_index="<<dig_index<<std::endl;\r
                                                client.setTempMod(nodepos, NodeMod(NODEMOD_CRACK, dig_index));\r
                                        }\r