diff --git a/src/Game.c b/src/Game.c index cd29e02c8..c74bd155b 100644 --- a/src/Game.c +++ b/src/Game.c @@ -649,6 +649,11 @@ static void Game_RunLoop(void) { /* Now thats there's a main loop, Game_SetFpsLimit will actually do something */ Game_SetFpsLimit(Options_GetEnum(OPT_FPS_LIMIT, 0, FpsLimit_Names, FPS_LIMIT_COUNT)); } + +cc_bool Game_ShouldClose(void) { + /* Running in multiplayer or map was saved within last 5 seconds */ + return !Server.IsSinglePlayer || (World.LastSave + 5 >= Game.Time); +} #else static void Game_RunLoop(void) { cc_uint64 lastRender, render; diff --git a/src/Game.h b/src/Game.h index d0c31e03b..de69a8194 100644 --- a/src/Game.h +++ b/src/Game.h @@ -78,6 +78,8 @@ void Game_SetFpsLimit(int method); /* Runs the main game loop until the window is closed. */ void Game_Run(int width, int height, const cc_string* title); +/* Whether the game should be allowed to automatically close */ +cc_bool Game_ShouldClose(void); /* Represents a game component. */ struct IGameComponent; diff --git a/src/Menus.c b/src/Menus.c index 0ace8c052..a446e83cb 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -1398,6 +1398,7 @@ static void SaveLevelScreen_SaveMap(struct SaveLevelScreen* s, const cc_string* #else Chat_Add1("&eSaved map to: %s", path); #endif + World.LastSave = Game.Time; Gui_ShowPauseMenu(); } diff --git a/src/Window.c b/src/Window.c index 9007e1031..07c2f0936 100644 --- a/src/Window.c +++ b/src/Window.c @@ -2745,6 +2745,7 @@ void Window_FreeFramebuffer(struct Bitmap* bmp) { #include #include #include +#include "Game.h" static cc_bool keyboardOpen, needResize; static int RawDpiScale(int x) { return (int)(x * emscripten_get_device_pixel_ratio()); } @@ -2908,6 +2909,12 @@ static EM_BOOL OnFullscreenChange(int type, const EmscriptenFullscreenChangeEven } static const char* OnBeforeUnload(int type, const void* ev, void *data) { + if (!Game_ShouldClose()) { + /* Exit pointer lock, otherwise when you press Ctrl+W, the */ + /* cursor remains invisible in the confirmation dialog */ + emscripten_exit_pointerlock(); + return "You have unsaved changes. Are you sure you want to quit?"; + } Window_Close(); return NULL; } diff --git a/src/World.c b/src/World.c index 958fe6ddb..834e75105 100644 --- a/src/World.c +++ b/src/World.c @@ -46,7 +46,8 @@ void World_Reset(void) { World.Blocks = NULL; World_SetDimensions(0, 0, 0); - World.Loaded = false; + World.Loaded = false; + World.LastSave = -200; Env_Reset(); } diff --git a/src/World.h b/src/World.h index b2d23b2f5..35fe083e2 100644 --- a/src/World.h +++ b/src/World.h @@ -44,6 +44,8 @@ CC_VAR extern struct _WorldData { /* Whether the world has finished loading/generating. */ /* NOTE: Blocks may still be NULL. (e.g. error during loading) */ cc_bool Loaded; + /* Point in time the current world was last saved at */ + double LastSave; } World; /* Frees the blocks array, sets dimensions to 0, resets environment to default. */