Query before destroying important structures (rail stations and industries)

Prior to this change, the use of NewObjects often lead to the problem of players trying to clear those and accidentally destroying a rail station or (when using magic bulldozer) an industry. This action cannot be undone.

This change shows a query making sure the player actually wants to destroy the station or industry.

NOTE: The switch to a std::function no longer allows for the inequality check in ShowQuery in misc_gui. If this was required a different solution has to be found.
This commit is contained in:
Andreas Schmitt
2021-06-11 18:10:46 +02:00
parent a7d8c6fe0c
commit 184ade43eb
5 changed files with 61 additions and 13 deletions

View File

@@ -12,6 +12,8 @@
#include "landscape.h"
#include "error.h"
#include "gui.h"
#include <utility>
#include "command_func.h"
#include "company_func.h"
#include "town.h"
@@ -1230,19 +1232,19 @@ void ShowQueryString(StringID str, StringID caption, uint maxsize, Window *paren
* Window used for asking the user a YES/NO question.
*/
struct QueryWindow : public Window {
QueryCallbackProc *proc; ///< callback function executed on closing of popup. Window* points to parent, bool is true if 'yes' clicked, false otherwise
QueryCallbackProc proc; ///< callback function executed on closing of popup. Window* points to parent, bool is true if 'yes' clicked, false otherwise
uint64 params[10]; ///< local copy of #_global_string_params
StringID message; ///< message shown for query window
StringID caption; ///< title of window
QueryWindow(WindowDesc *desc, StringID caption, StringID message, Window *parent, QueryCallbackProc *callback) : Window(desc)
QueryWindow(WindowDesc *desc, StringID caption, StringID message, Window *parent, QueryCallbackProc callback) : Window(desc)
{
/* Create a backup of the variadic arguments to strings because it will be
* overridden pretty often. We will copy these back for drawing */
CopyOutDParam(this->params, 0, lengthof(this->params));
this->caption = caption;
this->message = message;
this->proc = callback;
this->proc = std::move(callback);
this->parent = parent;
this->InitNested(WN_CONFIRM_POPUP_QUERY);
@@ -1299,7 +1301,7 @@ struct QueryWindow : public Window {
case WID_Q_YES: {
/* in the Generate New World window, clicking 'Yes' causes
* DeleteNonVitalWindows() to be called - we shouldn't be in a window then */
QueryCallbackProc *proc = this->proc;
QueryCallbackProc proc = this->proc;
Window *parent = this->parent;
/* Prevent the destructor calling the callback function */
this->proc = nullptr;
@@ -1364,9 +1366,9 @@ static WindowDesc _query_desc(
* @param message string that will be shown for the window
* @param parent pointer to parent window, if this pointer is nullptr the parent becomes
* the main window WC_MAIN_WINDOW
* @param callback callback function pointer to set in the window descriptor
* @param callback callback function to set in the window descriptor
*/
void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallbackProc *callback)
void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallbackProc callback)
{
if (parent == nullptr) parent = FindWindowById(WC_MAIN_WINDOW, 0);
@@ -1374,7 +1376,7 @@ void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallback
if (w->window_class != WC_CONFIRM_POPUP_QUERY) continue;
const QueryWindow *qw = (const QueryWindow *)w;
if (qw->parent != parent || qw->proc != callback) continue;
if (qw->parent != parent) continue;
delete qw;
break;