Map deletion button
This commit is contained in:
parent
d3a6a12bae
commit
035345f13d
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
53
src/main.cpp
53
src/main.cpp
|
@ -153,8 +153,10 @@ TODO: Optimize day/night mesh updating somehow
|
|||
meshbuffers? It should go quite fast.
|
||||
- This is not easy; There'd need to be a buffer somewhere
|
||||
that would contain the night and day lighting values.
|
||||
- Actually if FastFaces would be stored, they could
|
||||
hold both values
|
||||
|
||||
TODO: Combine MapBlock's face caches to so big pieces that VBO
|
||||
FEATURE: Combine MapBlock's face caches to so big pieces that VBO
|
||||
gets used
|
||||
- That is >500 vertices
|
||||
- This is not easy; all the MapBlocks close to the player would
|
||||
|
@ -181,6 +183,10 @@ TODO: Untie client network operations from framerate
|
|||
|
||||
TODO: Make morning and evening shorter
|
||||
|
||||
TODO: Don't update all meshes always on single node changes, but
|
||||
check which ones should be updated
|
||||
- implement Map::updateNodeMeshes()
|
||||
|
||||
Server:
|
||||
-------
|
||||
|
||||
|
@ -260,10 +266,15 @@ FEATURE: The map could be generated procedually:
|
|||
- How about relocating minerals, too? Coal and gold in
|
||||
downstream sand and gravel would be kind of cool
|
||||
- This would need a better way of handling minerals, mainly
|
||||
to have mineral content as a separate field
|
||||
to have mineral content as a separate field. the first
|
||||
parameter field is free for this.
|
||||
- Simulate rock falling from cliffs when water has removed
|
||||
enough solid rock from the bottom
|
||||
|
||||
TODO: Mineral and ground material properties
|
||||
- This way mineral ground toughness can be calculated with just
|
||||
some formula, as well as tool strengths
|
||||
|
||||
TODO: Change AttributeList to split the area into smaller sections so
|
||||
that searching won't be as heavy.
|
||||
|
||||
|
@ -308,6 +319,7 @@ Doing now:
|
|||
#pragma comment(lib, "Irrlicht.lib")
|
||||
//#pragma comment(lib, "jthread.lib")
|
||||
#pragma comment(lib, "zlibwapi.lib")
|
||||
#pragma comment(lib, "Shell32.lib")
|
||||
// This would get rid of the console window
|
||||
//#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
|
||||
#endif
|
||||
|
@ -1270,9 +1282,12 @@ int main(int argc, char *argv[])
|
|||
porting::initializePaths();
|
||||
// Create user data directory
|
||||
fs::CreateDir(porting::path_userdata);
|
||||
|
||||
|
||||
// C-style stuff initialization
|
||||
initializeMaterialProperties();
|
||||
init_mapnode();
|
||||
|
||||
// Debug handler
|
||||
BEGIN_DEBUG_EXCEPTION_HANDLER
|
||||
|
||||
// Print startup message
|
||||
|
@ -1550,7 +1565,7 @@ int main(int argc, char *argv[])
|
|||
*/
|
||||
|
||||
init_content_inventory_texture_paths();
|
||||
init_tile_textures();
|
||||
//init_tile_textures();
|
||||
|
||||
/*
|
||||
GUI stuff
|
||||
|
@ -1608,10 +1623,10 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
|
||||
/*
|
||||
Out-of-game menu loop
|
||||
Out-of-game menu loop.
|
||||
|
||||
Loop quits when menu returns proper parameters.
|
||||
*/
|
||||
|
||||
// Wait for proper parameters
|
||||
for(;;)
|
||||
{
|
||||
// Cursor can be non-visible when coming from the game
|
||||
|
@ -1671,6 +1686,15 @@ int main(int argc, char *argv[])
|
|||
dstream<<"Dropping main menu"<<std::endl;
|
||||
|
||||
menu->drop();
|
||||
|
||||
// Delete map if requested
|
||||
if(menudata.delete_map)
|
||||
{
|
||||
bool r = fs::RecursiveDeleteContent(map_dir);
|
||||
if(r == false)
|
||||
error_message = L"Delete failed";
|
||||
continue;
|
||||
}
|
||||
|
||||
playername = wide_to_narrow(menudata.name);
|
||||
address = wide_to_narrow(menudata.address);
|
||||
|
@ -2386,8 +2410,20 @@ int main(int argc, char *argv[])
|
|||
|
||||
static float dig_time = 0.0;
|
||||
static u16 dig_index = 0;
|
||||
|
||||
// Visualize selection
|
||||
|
||||
hilightboxes.push_back(nodefacebox);
|
||||
const float d = 0.502;
|
||||
core::aabbox3d<f32> nodebox(-BS*d, -BS*d, -BS*d, BS*d, BS*d, BS*d);
|
||||
v3f nodepos_f = intToFloat(nodepos);
|
||||
//v3f nodepos_f(nodepos.X*BS, nodepos.Y*BS, nodepos.Z*BS);
|
||||
nodebox.MinEdge += nodepos_f;
|
||||
nodebox.MaxEdge += nodepos_f;
|
||||
hilightboxes.push_back(nodebox);
|
||||
|
||||
//hilightboxes.push_back(nodefacebox);
|
||||
|
||||
// Handle digging
|
||||
|
||||
if(g_input->getLeftReleased())
|
||||
{
|
||||
|
@ -2473,6 +2509,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
if(dig_index < CRACK_ANIMATION_LENGTH)
|
||||
{
|
||||
//TimeTaker timer("client.setTempMod");
|
||||
//dstream<<"dig_index="<<dig_index<<std::endl;
|
||||
client.setTempMod(nodepos, NodeMod(NODEMOD_CRACK, dig_index));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue