diff --git a/src/viewport.cpp b/src/viewport.cpp index 10369e1ec9..f090a7565c 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -2708,11 +2708,18 @@ void SetObjectToPlaceWnd(CursorID icon, SpriteID pal, ViewportHighlightMode mode void SetObjectToPlace(CursorID icon, SpriteID pal, ViewportHighlightMode mode, WindowClass window_class, WindowNumber window_num) { - Window *w = NULL; - /* undo clicking on button and drag & drop */ if (_thd.place_mode != VHM_NONE || _special_mouse_mode == WSM_DRAGDROP) { - w = FindWindowById(_thd.window_class, _thd.window_number); + Window *w = FindWindowById(_thd.window_class, _thd.window_number); + if (w != NULL) { + /* Call the abort function, but set the window class to something + * that will never be used to avoid infinite loops. Setting it to + * the 'next' window class must not be done because recursion into + * this function might in some cases reset the newly set object to + * place or not properly reset the original selection. */ + _thd.window_class = WC_INVALID; + w->OnPlaceObjectAbort(); + } } SetTileSelectSize(1, 1); @@ -2739,10 +2746,6 @@ void SetObjectToPlace(CursorID icon, SpriteID pal, ViewportHighlightMode mode, W SetMouseCursor(icon, pal); } - /* Call the abort function only *after* the window class/number - * are reset so one doesn't get into infinite loops when someone - * resets the object to place during the abort callback. */ - if (w != NULL) w->OnPlaceObjectAbort(); } void ResetObjectToPlace() diff --git a/src/window_type.h b/src/window_type.h index f1952d1d5b..86071a8304 100644 --- a/src/window_type.h +++ b/src/window_type.h @@ -94,6 +94,8 @@ enum WindowClass { WC_BUILD_SIGNAL, WC_COMPANY_PASSWORD_WINDOW, WC_OSK, + + WC_INVALID = 0xFFFF }; struct Window;