Merge remote-tracking branch 'upstream/develop' into new-save-format

This commit is contained in:
ζeh Matt 2021-10-06 19:47:09 +03:00
commit b96565266c
No known key found for this signature in database
GPG Key ID: 18CE582C71A225B0
57 changed files with 1039 additions and 1146 deletions

View File

@ -177,6 +177,7 @@ The following people are not part of the development team, but have been contrib
* Saad Rehman (SaadRehmanCS)
* (ocalhoun6)
* Sean Payne (seanmajorpayne)
* Soham Roy (sohamroy19)
## Toolchain
* (Balletie) - macOS

View File

@ -3651,6 +3651,8 @@ STR_6453 :Versionsinfo kopieren
STR_6454 :Kann Banner nicht umbenennen …
STR_6455 :Kann Schild nicht umbenennen …
STR_6456 :Riesiger Screenshot
STR_6457 :Einen Fehler auf GitHub melden
STR_6458 :Dies in Hauptansicht folgen
#############
# Scenarios #

View File

@ -3610,6 +3610,9 @@ STR_6406 :Instalador de GOG RollerCoaster Tycoon 2
STR_6407 :Puede tardar unos minutos.
STR_6408 :Please install “innoextract” to extract GOG Installer, then restart OpenRCT2. Instale "innoextract" para extraer el Instalador de GOG y luego reinicie OpenRCT2.
STR_6409 :El archivo seleccionado no es el Instalador sin conexión de GOG para RollerCoaster Tycoon 2. Puede que hayas descargado GOG Galaxy downloader stub o ha seleccionado el archivo incorrecto.
STR_6454 :No se puede cambiar el nombre del banner…
STR_6455 :No se puede cambiar el nombre del señal…
##############
# Escenarios #
##############

View File

@ -30,6 +30,7 @@
- Fix: [#15476] Crash when placing/clearing small scenery.
- Fix: [#15487] Map animations do not work correctly when loading an exported SV6 file in vanilla RCT2.
- Fix: [#15496] Crash in paint_swinging_inverter_ship_structure().
- Fix: [#15514] Two different “quit to menu” menu items are available in track designer and track design manager.
- Improved: [#3417] Crash dumps are now placed in their own folder.
- Change: [#8601] Revert ToonTower base block fix to re-enable support blocking.
- Change: [#15174] [Plugin] Deprecate the type "peep" and add support to target a specific scripting api version.

View File

@ -194,27 +194,27 @@ static void InputScrollDragContinue(const ScreenCoordsXY& screenCoords, rct_wind
rct_widgetindex widgetIndex = _dragWidget.widget_index;
uint8_t scrollIndex = _dragScrollIndex;
rct_widget* widget = &w->widgets[widgetIndex];
rct_scroll* scroll = &w->scrolls[scrollIndex];
const auto& widget = w->widgets[widgetIndex];
auto& scroll = w->scrolls[scrollIndex];
ScreenCoordsXY differentialCoords = screenCoords - gInputDragLast;
if (scroll->flags & HSCROLLBAR_VISIBLE)
if (scroll.flags & HSCROLLBAR_VISIBLE)
{
int16_t size = widget->width() - 1;
if (scroll->flags & VSCROLLBAR_VISIBLE)
int16_t size = widget.width() - 1;
if (scroll.flags & VSCROLLBAR_VISIBLE)
size -= 11;
size = std::max(0, scroll->h_right - size);
scroll->h_left = std::min<uint16_t>(std::max(0, scroll->h_left + differentialCoords.x), size);
size = std::max(0, scroll.h_right - size);
scroll.h_left = std::min<uint16_t>(std::max(0, scroll.h_left + differentialCoords.x), size);
}
if (scroll->flags & VSCROLLBAR_VISIBLE)
if (scroll.flags & VSCROLLBAR_VISIBLE)
{
int16_t size = widget->height() - 1;
if (scroll->flags & HSCROLLBAR_VISIBLE)
int16_t size = widget.height() - 1;
if (scroll.flags & HSCROLLBAR_VISIBLE)
size -= 11;
size = std::max(0, scroll->v_bottom - size);
scroll->v_top = std::min<uint16_t>(std::max(0, scroll->v_top + differentialCoords.y), size);
size = std::max(0, scroll.v_bottom - size);
scroll.v_top = std::min<uint16_t>(std::max(0, scroll.v_top + differentialCoords.y), size);
}
WidgetScrollUpdateThumbs(w, widgetIndex);
@ -604,9 +604,7 @@ static void InputViewportDragEnd()
static void InputScrollBegin(rct_window* w, rct_widgetindex widgetIndex, const ScreenCoordsXY& screenCoords)
{
rct_widget* widget;
widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
_inputState = InputState::ScrollLeft;
gPressedWidget.window_classification = w->classification;
@ -617,7 +615,7 @@ static void InputScrollBegin(rct_window* w, rct_widgetindex widgetIndex, const S
int32_t scroll_area, scroll_id;
ScreenCoordsXY scrollCoords;
scroll_id = 0; // safety
WidgetScrollGetPart(w, widget, screenCoords, scrollCoords, &scroll_area, &scroll_id);
WidgetScrollGetPart(w, &widget, screenCoords, scrollCoords, &scroll_area, &scroll_id);
_currentScrollArea = scroll_area;
_currentScrollIndex = scroll_id;
@ -628,44 +626,44 @@ static void InputScrollBegin(rct_window* w, rct_widgetindex widgetIndex, const S
return;
}
rct_widget* widg = &w->widgets[widgetIndex];
rct_scroll* scroll = &w->scrolls[scroll_id];
const auto& widg = w->widgets[widgetIndex];
auto& scroll = w->scrolls[scroll_id];
int32_t widget_width = widg->width() - 1;
if (scroll->flags & VSCROLLBAR_VISIBLE)
int32_t widget_width = widg.width() - 1;
if (scroll.flags & VSCROLLBAR_VISIBLE)
widget_width -= SCROLLBAR_WIDTH + 1;
int32_t widget_content_width = std::max(scroll->h_right - widget_width, 0);
int32_t widget_content_width = std::max(scroll.h_right - widget_width, 0);
int32_t widget_height = widg->bottom - widg->top - 1;
if (scroll->flags & HSCROLLBAR_VISIBLE)
int32_t widget_height = widg.bottom - widg.top - 1;
if (scroll.flags & HSCROLLBAR_VISIBLE)
widget_height -= SCROLLBAR_WIDTH + 1;
int32_t widget_content_height = std::max(scroll->v_bottom - widget_height, 0);
int32_t widget_content_height = std::max(scroll.v_bottom - widget_height, 0);
switch (scroll_area)
{
case SCROLL_PART_HSCROLLBAR_LEFT:
scroll->h_left = std::max(scroll->h_left - 3, 0);
scroll.h_left = std::max(scroll.h_left - 3, 0);
break;
case SCROLL_PART_HSCROLLBAR_RIGHT:
scroll->h_left = std::min(scroll->h_left + 3, widget_content_width);
scroll.h_left = std::min(scroll.h_left + 3, widget_content_width);
break;
case SCROLL_PART_HSCROLLBAR_LEFT_TROUGH:
scroll->h_left = std::max(scroll->h_left - widget_width, 0);
scroll.h_left = std::max(scroll.h_left - widget_width, 0);
break;
case SCROLL_PART_HSCROLLBAR_RIGHT_TROUGH:
scroll->h_left = std::min(scroll->h_left + widget_width, widget_content_width);
scroll.h_left = std::min(scroll.h_left + widget_width, widget_content_width);
break;
case SCROLL_PART_VSCROLLBAR_TOP:
scroll->v_top = std::max(scroll->v_top - 3, 0);
scroll.v_top = std::max(scroll.v_top - 3, 0);
break;
case SCROLL_PART_VSCROLLBAR_BOTTOM:
scroll->v_top = std::min(scroll->v_top + 3, widget_content_height);
scroll.v_top = std::min(scroll.v_top + 3, widget_content_height);
break;
case SCROLL_PART_VSCROLLBAR_TOP_TROUGH:
scroll->v_top = std::max(scroll->v_top - widget_height, 0);
scroll.v_top = std::max(scroll.v_top - widget_height, 0);
break;
case SCROLL_PART_VSCROLLBAR_BOTTOM_TROUGH:
scroll->v_top = std::min(scroll->v_top + widget_height, widget_content_height);
scroll.v_top = std::min(scroll.v_top + widget_height, widget_content_height);
break;
default:
break;
@ -676,12 +674,11 @@ static void InputScrollBegin(rct_window* w, rct_widgetindex widgetIndex, const S
static void InputScrollContinue(rct_window* w, rct_widgetindex widgetIndex, const ScreenCoordsXY& screenCoords)
{
rct_widget* widget;
int32_t scroll_part, scroll_id;
assert(w != nullptr);
widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
if (w->classification != gPressedWidget.window_classification || w->number != gPressedWidget.window_number
|| widgetIndex != gPressedWidget.widget_index)
{
@ -690,7 +687,7 @@ static void InputScrollContinue(rct_window* w, rct_widgetindex widgetIndex, cons
}
ScreenCoordsXY newScreenCoords;
WidgetScrollGetPart(w, widget, screenCoords, newScreenCoords, &scroll_part, &scroll_id);
WidgetScrollGetPart(w, &widget, screenCoords, newScreenCoords, &scroll_part, &scroll_id);
if (_currentScrollArea == SCROLL_PART_HSCROLLBAR_THUMB)
{
@ -746,33 +743,34 @@ static void InputScrollEnd()
*/
static void InputScrollPartUpdateHThumb(rct_window* w, rct_widgetindex widgetIndex, int32_t x, int32_t scroll_id)
{
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
auto& scroll = w->scrolls[scroll_id];
if (window_find_by_number(w->classification, w->number) != nullptr)
{
int32_t newLeft;
newLeft = w->scrolls[scroll_id].h_right;
newLeft = scroll.h_right;
newLeft *= x;
x = widget->width() - 21;
if (w->scrolls[scroll_id].flags & VSCROLLBAR_VISIBLE)
x = widget.width() - 21;
if (scroll.flags & VSCROLLBAR_VISIBLE)
x -= SCROLLBAR_WIDTH + 1;
newLeft /= x;
x = newLeft;
w->scrolls[scroll_id].flags |= HSCROLLBAR_THUMB_PRESSED;
newLeft = w->scrolls[scroll_id].h_left;
scroll.flags |= HSCROLLBAR_THUMB_PRESSED;
newLeft = scroll.h_left;
newLeft += x;
if (newLeft < 0)
newLeft = 0;
x = widget->width() - 1;
if (w->scrolls[scroll_id].flags & VSCROLLBAR_VISIBLE)
x = widget.width() - 1;
if (scroll.flags & VSCROLLBAR_VISIBLE)
x -= SCROLLBAR_WIDTH + 1;
x *= -1;
x += w->scrolls[scroll_id].h_right;
x += scroll.h_right;
if (x < 0)
x = 0;
if (newLeft > x)
newLeft = x;
w->scrolls[scroll_id].h_left = newLeft;
scroll.h_left = newLeft;
WidgetScrollUpdateThumbs(w, widgetIndex);
widget_invalidate_by_number(w->classification, w->number, widgetIndex);
}
@ -785,33 +783,34 @@ static void InputScrollPartUpdateHThumb(rct_window* w, rct_widgetindex widgetInd
static void InputScrollPartUpdateVThumb(rct_window* w, rct_widgetindex widgetIndex, int32_t y, int32_t scroll_id)
{
assert(w != nullptr);
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
auto& scroll = w->scrolls[scroll_id];
if (window_find_by_number(w->classification, w->number) != nullptr)
{
int32_t newTop;
newTop = w->scrolls[scroll_id].v_bottom;
newTop = scroll.v_bottom;
newTop *= y;
y = widget->height() - 21;
if (w->scrolls[scroll_id].flags & HSCROLLBAR_VISIBLE)
y = widget.height() - 21;
if (scroll.flags & HSCROLLBAR_VISIBLE)
y -= SCROLLBAR_WIDTH + 1;
newTop /= y;
y = newTop;
w->scrolls[scroll_id].flags |= VSCROLLBAR_THUMB_PRESSED;
newTop = w->scrolls[scroll_id].v_top;
scroll.flags |= VSCROLLBAR_THUMB_PRESSED;
newTop = scroll.v_top;
newTop += y;
if (newTop < 0)
newTop = 0;
y = widget->height() - 1;
if (w->scrolls[scroll_id].flags & HSCROLLBAR_VISIBLE)
y = widget.height() - 1;
if (scroll.flags & HSCROLLBAR_VISIBLE)
y -= SCROLLBAR_WIDTH + 1;
y *= -1;
y += w->scrolls[scroll_id].v_bottom;
y += scroll.v_bottom;
if (y < 0)
y = 0;
if (newTop > y)
newTop = y;
w->scrolls[scroll_id].v_top = newTop;
scroll.v_top = newTop;
WidgetScrollUpdateThumbs(w, widgetIndex);
widget_invalidate_by_number(w->classification, w->number, widgetIndex);
}
@ -826,9 +825,10 @@ static void InputScrollPartUpdateHLeft(rct_window* w, rct_widgetindex widgetInde
assert(w != nullptr);
if (window_find_by_number(w->classification, w->number) != nullptr)
{
w->scrolls[scroll_id].flags |= HSCROLLBAR_LEFT_PRESSED;
if (w->scrolls[scroll_id].h_left >= 3)
w->scrolls[scroll_id].h_left -= 3;
auto& scroll = w->scrolls[scroll_id];
scroll.flags |= HSCROLLBAR_LEFT_PRESSED;
if (scroll.h_left >= 3)
scroll.h_left -= 3;
WidgetScrollUpdateThumbs(w, widgetIndex);
widget_invalidate_by_number(w->classification, w->number, widgetIndex);
}
@ -841,20 +841,21 @@ static void InputScrollPartUpdateHLeft(rct_window* w, rct_widgetindex widgetInde
static void InputScrollPartUpdateHRight(rct_window* w, rct_widgetindex widgetIndex, int32_t scroll_id)
{
assert(w != nullptr);
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
if (window_find_by_number(w->classification, w->number) != nullptr)
{
w->scrolls[scroll_id].flags |= HSCROLLBAR_RIGHT_PRESSED;
w->scrolls[scroll_id].h_left += 3;
int32_t newLeft = widget->width() - 1;
if (w->scrolls[scroll_id].flags & VSCROLLBAR_VISIBLE)
auto& scroll = w->scrolls[scroll_id];
scroll.flags |= HSCROLLBAR_RIGHT_PRESSED;
scroll.h_left += 3;
int32_t newLeft = widget.width() - 1;
if (scroll.flags & VSCROLLBAR_VISIBLE)
newLeft -= SCROLLBAR_WIDTH + 1;
newLeft *= -1;
newLeft += w->scrolls[scroll_id].h_right;
newLeft += scroll.h_right;
if (newLeft < 0)
newLeft = 0;
if (w->scrolls[scroll_id].h_left > newLeft)
w->scrolls[scroll_id].h_left = newLeft;
if (scroll.h_left > newLeft)
scroll.h_left = newLeft;
WidgetScrollUpdateThumbs(w, widgetIndex);
widget_invalidate_by_number(w->classification, w->number, widgetIndex);
}
@ -869,9 +870,10 @@ static void InputScrollPartUpdateVTop(rct_window* w, rct_widgetindex widgetIndex
assert(w != nullptr);
if (window_find_by_number(w->classification, w->number) != nullptr)
{
w->scrolls[scroll_id].flags |= VSCROLLBAR_UP_PRESSED;
if (w->scrolls[scroll_id].v_top >= 3)
w->scrolls[scroll_id].v_top -= 3;
auto& scroll = w->scrolls[scroll_id];
scroll.flags |= VSCROLLBAR_UP_PRESSED;
if (scroll.v_top >= 3)
scroll.v_top -= 3;
WidgetScrollUpdateThumbs(w, widgetIndex);
widget_invalidate_by_number(w->classification, w->number, widgetIndex);
}
@ -884,20 +886,21 @@ static void InputScrollPartUpdateVTop(rct_window* w, rct_widgetindex widgetIndex
static void InputScrollPartUpdateVBottom(rct_window* w, rct_widgetindex widgetIndex, int32_t scroll_id)
{
assert(w != nullptr);
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
if (window_find_by_number(w->classification, w->number) != nullptr)
{
w->scrolls[scroll_id].flags |= VSCROLLBAR_DOWN_PRESSED;
w->scrolls[scroll_id].v_top += 3;
int32_t newTop = widget->height() - 1;
if (w->scrolls[scroll_id].flags & HSCROLLBAR_VISIBLE)
auto& scroll = w->scrolls[scroll_id];
scroll.flags |= VSCROLLBAR_DOWN_PRESSED;
scroll.v_top += 3;
int32_t newTop = widget.height() - 1;
if (scroll.flags & HSCROLLBAR_VISIBLE)
newTop -= SCROLLBAR_WIDTH + 1;
newTop *= -1;
newTop += w->scrolls[scroll_id].v_bottom;
newTop += scroll.v_bottom;
if (newTop < 0)
newTop = 0;
if (w->scrolls[scroll_id].v_top > newTop)
w->scrolls[scroll_id].v_top = newTop;
if (scroll.v_top > newTop)
scroll.v_top = newTop;
WidgetScrollUpdateThumbs(w, widgetIndex);
widget_invalidate_by_number(w->classification, w->number, widgetIndex);
}
@ -1000,7 +1003,6 @@ static void InputWidgetLeft(const ScreenCoordsXY& screenCoords, rct_window* w, r
{
rct_windowclass windowClass = WC_NULL;
rct_windownumber windowNumber = 0;
rct_widget* widget;
if (w != nullptr)
{
@ -1026,9 +1028,9 @@ static void InputWidgetLeft(const ScreenCoordsXY& screenCoords, rct_window* w, r
window_cancel_textbox();
}
widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
switch (widget->type)
switch (widget.type)
{
case WindowWidgetType::Frame:
case WindowWidgetType::Resize:
@ -1060,7 +1062,7 @@ static void InputWidgetLeft(const ScreenCoordsXY& screenCoords, rct_window* w, r
default:
if (WidgetIsEnabled(w, widgetIndex) && !WidgetIsDisabled(w, widgetIndex))
{
OpenRCT2::Audio::Play(OpenRCT2::Audio::SoundId::Click1, 0, w->windowPos.x + widget->midX());
OpenRCT2::Audio::Play(OpenRCT2::Audio::SoundId::Click1, 0, w->windowPos.x + widget.midX());
// Set new cursor down widget
gPressedWidget.window_classification = windowClass;

View File

@ -36,9 +36,9 @@ static void WidgetCheckboxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widget
static void WidgetCloseboxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex);
static void WidgetScrollDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex);
static void WidgetHScrollbarDraw(
rct_drawpixelinfo* dpi, rct_scroll* scroll, int32_t l, int32_t t, int32_t r, int32_t b, int32_t colour);
rct_drawpixelinfo* dpi, const rct_scroll& scroll, int32_t l, int32_t t, int32_t r, int32_t b, int32_t colour);
static void WidgetVScrollbarDraw(
rct_drawpixelinfo* dpi, rct_scroll* scroll, int32_t l, int32_t t, int32_t r, int32_t b, int32_t colour);
rct_drawpixelinfo* dpi, const rct_scroll& scroll, int32_t l, int32_t t, int32_t r, int32_t b, int32_t colour);
static void WidgetDrawImage(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex);
/**
@ -47,7 +47,8 @@ static void WidgetDrawImage(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetind
*/
void WidgetDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex)
{
switch (w->widgets[widgetIndex].type)
const auto& widget = w->widgets[widgetIndex];
switch (widget.type)
{
case WindowWidgetType::Frame:
WidgetFrameDraw(dpi, w, widgetIndex);
@ -111,18 +112,18 @@ void WidgetDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetInd
static void WidgetFrameDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex)
{
// Get the widget
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
// Resolve the absolute ltrb
auto leftTop = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
int32_t r = w->windowPos.x + widget->right;
int32_t b = w->windowPos.y + widget->bottom;
auto leftTop = w->windowPos + ScreenCoordsXY{ widget.left, widget.top };
int32_t r = w->windowPos.x + widget.right;
int32_t b = w->windowPos.y + widget.bottom;
//
uint8_t press = ((w->flags & WF_10) ? INSET_RECT_FLAG_FILL_MID_LIGHT : 0);
// Get the colour
uint8_t colour = w->colours[widget->colour];
uint8_t colour = w->colours[widget.colour];
// Draw the frame
gfx_fill_rect_inset(dpi, { leftTop, { r, b } }, colour, press);
@ -134,7 +135,7 @@ static void WidgetFrameDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetind
return;
// Draw the resize sprite at the bottom right corner
leftTop = w->windowPos + ScreenCoordsXY{ widget->right - 18, widget->bottom - 18 };
leftTop = w->windowPos + ScreenCoordsXY{ widget.right - 18, widget.bottom - 18 };
gfx_draw_sprite(dpi, ImageId(SPR_RESIZE, colour & 0x7F), leftTop);
}
@ -145,15 +146,15 @@ static void WidgetFrameDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetind
static void WidgetResizeDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex)
{
// Get the widget
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
// Resolve the absolute ltrb
auto leftTop = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
int32_t r = w->windowPos.x + widget->right;
int32_t b = w->windowPos.y + widget->bottom;
auto leftTop = w->windowPos + ScreenCoordsXY{ widget.left, widget.top };
int32_t r = w->windowPos.x + widget.right;
int32_t b = w->windowPos.y + widget.bottom;
// Get the colour
uint8_t colour = w->colours[widget->colour];
uint8_t colour = w->colours[widget.colour];
// Draw the panel
gfx_fill_rect_inset(dpi, { leftTop, { r, b } }, colour, 0);
@ -165,7 +166,7 @@ static void WidgetResizeDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetin
return;
// Draw the resize sprite at the bottom right corner
leftTop = w->windowPos + ScreenCoordsXY{ widget->right - 18, widget->bottom - 18 };
leftTop = w->windowPos + ScreenCoordsXY{ widget.right - 18, widget.bottom - 18 };
gfx_draw_sprite(dpi, ImageId(SPR_RESIZE, colour & 0x7F), leftTop);
}
@ -176,19 +177,19 @@ static void WidgetResizeDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetin
static void WidgetButtonDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex)
{
// Get the widget
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
// Resolve the absolute ltrb
ScreenRect rect{ w->windowPos + ScreenCoordsXY{ widget->left, widget->top },
w->windowPos + ScreenCoordsXY{ widget->right, widget->bottom } };
ScreenRect rect{ w->windowPos + ScreenCoordsXY{ widget.left, widget.top },
w->windowPos + ScreenCoordsXY{ widget.right, widget.bottom } };
// Check if the button is pressed down
uint8_t press = WidgetIsPressed(w, widgetIndex) || WidgetIsActiveTool(w, widgetIndex) ? INSET_RECT_FLAG_BORDER_INSET : 0;
// Get the colour
uint8_t colour = w->colours[widget->colour];
uint8_t colour = w->colours[widget.colour];
if (static_cast<int32_t>(widget->image) == -2)
if (static_cast<int32_t>(widget.image) == -2)
{
// Draw border with no fill
gfx_fill_rect_inset(dpi, rect, colour, press | INSET_RECT_FLAG_FILL_NONE);
@ -208,20 +209,20 @@ static void WidgetButtonDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetin
static void WidgetTabDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex)
{
// Get the widget
rct_widget* widget = &w->widgets[widgetIndex];
auto& widget = w->widgets[widgetIndex];
if (widget->type != WindowWidgetType::Tab && static_cast<int32_t>(widget->image) == -1)
if (widget.type != WindowWidgetType::Tab && static_cast<int32_t>(widget.image) == -1)
return;
if (widget->type == WindowWidgetType::Tab)
if (widget.type == WindowWidgetType::Tab)
{
if (WidgetIsDisabled(w, widgetIndex))
return;
if (widget->image == static_cast<uint32_t>(SPR_NONE))
if (widget.image == static_cast<uint32_t>(SPR_NONE))
{
// Set standard tab sprite to use.
widget->image = IMAGE_TYPE_REMAP | SPR_TAB;
widget.image = IMAGE_TYPE_REMAP | SPR_TAB;
}
}
@ -232,18 +233,18 @@ static void WidgetTabDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex
return;
}
if (widget->type != WindowWidgetType::TrnBtn)
if (widget.type != WindowWidgetType::TrnBtn)
{
WidgetDrawImage(dpi, w, widgetIndex);
return;
}
// Resolve the absolute ltrb
auto leftTop = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
auto leftTop = w->windowPos + ScreenCoordsXY{ widget.left, widget.top };
// Get the colour and disabled image
uint8_t colour = w->colours[widget->colour] & 0x7F;
uint32_t image = widget->image + 2;
uint8_t colour = w->colours[widget.colour] & 0x7F;
uint32_t image = widget.image + 2;
// Draw disabled image
gfx_draw_sprite(dpi, ImageId(image, colour), leftTop);
@ -262,19 +263,19 @@ static void WidgetFlatButtonDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widg
}
// Get the widget
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
// Resolve the absolute ltrb
ScreenRect rect{ w->windowPos + ScreenCoordsXY{ widget->left, widget->top },
w->windowPos + ScreenCoordsXY{ widget->right, widget->bottom } };
ScreenRect rect{ w->windowPos + ScreenCoordsXY{ widget.left, widget.top },
w->windowPos + ScreenCoordsXY{ widget.right, widget.bottom } };
// Get the colour
uint8_t colour = w->colours[widget->colour];
uint8_t colour = w->colours[widget.colour];
// Check if the button is pressed down
if (WidgetIsPressed(w, widgetIndex) || WidgetIsActiveTool(w, widgetIndex))
{
if (static_cast<int32_t>(widget->image) == -2)
if (static_cast<int32_t>(widget.image) == -2)
{
// Draw border with no fill
gfx_fill_rect_inset(dpi, rect, colour, INSET_RECT_FLAG_BORDER_INSET | INSET_RECT_FLAG_FILL_NONE);
@ -296,21 +297,21 @@ static void WidgetFlatButtonDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widg
static void WidgetTextButton(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex)
{
// Get the widget
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
// Resolve the absolute ltrb
ScreenRect rect{ w->windowPos + ScreenCoordsXY{ widget->left, widget->top },
w->windowPos + ScreenCoordsXY{ widget->right, widget->bottom } };
ScreenRect rect{ w->windowPos + ScreenCoordsXY{ widget.left, widget.top },
w->windowPos + ScreenCoordsXY{ widget.right, widget.bottom } };
// Get the colour
uint8_t colour = w->colours[widget->colour];
uint8_t colour = w->colours[widget.colour];
// Border
uint8_t press = WidgetIsPressed(w, widgetIndex) || WidgetIsActiveTool(w, widgetIndex) ? INSET_RECT_FLAG_BORDER_INSET : 0;
gfx_fill_rect_inset(dpi, rect, colour, press);
// Button caption
if (widget->type != WindowWidgetType::TableHeader)
if (widget.type != WindowWidgetType::TableHeader)
{
WidgetTextCentred(dpi, w, widgetIndex);
}
@ -327,42 +328,42 @@ static void WidgetTextButton(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetin
static void WidgetTextCentred(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex)
{
// Get the widget
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
if (widget->text == STR_NONE)
if (widget.text == STR_NONE)
return;
// Get the colour
colour_t colour = w->colours[widget->colour];
colour_t colour = w->colours[widget.colour];
colour &= ~(COLOUR_FLAG_TRANSLUCENT);
if (WidgetIsDisabled(w, widgetIndex))
colour |= COLOUR_FLAG_INSET;
// Resolve the absolute ltrb
auto topLeft = w->windowPos + ScreenCoordsXY{ widget->left, 0 };
int32_t r = w->windowPos.x + widget->right;
auto topLeft = w->windowPos + ScreenCoordsXY{ widget.left, 0 };
int32_t r = w->windowPos.x + widget.right;
if (widget->type == WindowWidgetType::Button || widget->type == WindowWidgetType::TableHeader)
topLeft.y += widget->textTop();
if (widget.type == WindowWidgetType::Button || widget.type == WindowWidgetType::TableHeader)
topLeft.y += widget.textTop();
else
topLeft.y += widget->top;
topLeft.y += widget.top;
auto stringId = widget->text;
auto stringId = widget.text;
auto ft = Formatter::Common();
if (widget->flags & WIDGET_FLAGS::TEXT_IS_STRING)
if (widget.flags & WIDGET_FLAGS::TEXT_IS_STRING)
{
stringId = STR_STRING;
ft.Add<utf8*>(widget->string);
ft.Add<utf8*>(widget.string);
}
ScreenCoordsXY coords = { (topLeft.x + r + 1) / 2 - 1, topLeft.y };
if (widget->type == WindowWidgetType::LabelCentred)
if (widget.type == WindowWidgetType::LabelCentred)
{
DrawTextWrapped(dpi, coords, widget->width() - 2, stringId, ft, { colour, TextAlignment::CENTRE });
DrawTextWrapped(dpi, coords, widget.width() - 2, stringId, ft, { colour, TextAlignment::CENTRE });
}
else
{
DrawTextEllipsised(dpi, coords, widget->width() - 2, stringId, ft, { colour, TextAlignment::CENTRE });
DrawTextEllipsised(dpi, coords, widget.width() - 2, stringId, ft, { colour, TextAlignment::CENTRE });
}
}
@ -373,39 +374,39 @@ static void WidgetTextCentred(rct_drawpixelinfo* dpi, rct_window* w, rct_widgeti
static void WidgetText(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex)
{
// Get the widget
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
if (widget->text == STR_NONE || widget->text == STR_VIEWPORT)
if (widget.text == STR_NONE || widget.text == STR_VIEWPORT)
return;
// Get the colour
uint8_t colour = w->colours[widget->colour];
uint8_t colour = w->colours[widget.colour];
if (WidgetIsDisabled(w, widgetIndex))
colour |= COLOUR_FLAG_INSET;
// Resolve the absolute ltrb
int32_t l = w->windowPos.x + widget->left;
int32_t r = w->windowPos.x + widget->right;
int32_t l = w->windowPos.x + widget.left;
int32_t r = w->windowPos.x + widget.right;
int32_t t;
if (widget->type == WindowWidgetType::Button || widget->type == WindowWidgetType::DropdownMenu
|| widget->type == WindowWidgetType::Spinner || widget->type == WindowWidgetType::TableHeader)
if (widget.type == WindowWidgetType::Button || widget.type == WindowWidgetType::DropdownMenu
|| widget.type == WindowWidgetType::Spinner || widget.type == WindowWidgetType::TableHeader)
{
t = w->windowPos.y + widget->textTop();
t = w->windowPos.y + widget.textTop();
}
else
t = w->windowPos.y + widget->top;
t = w->windowPos.y + widget.top;
auto stringId = widget->text;
auto stringId = widget.text;
auto ft = Formatter::Common();
if (widget->flags & WIDGET_FLAGS::TEXT_IS_STRING)
if (widget.flags & WIDGET_FLAGS::TEXT_IS_STRING)
{
stringId = STR_STRING;
ft.Add<utf8*>(widget->string);
ft.Add<utf8*>(widget.string);
}
ScreenCoordsXY coords = { l + 1, t };
if (widget->type == WindowWidgetType::LabelCentred)
if (widget.type == WindowWidgetType::LabelCentred)
{
DrawTextWrapped(dpi, coords, r - l, stringId, ft, { colour, TextAlignment::CENTRE });
}
@ -422,26 +423,26 @@ static void WidgetText(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex wi
static void WidgetTextInset(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex)
{
// Get the widget
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
// Resolve the absolute ltrb
ScreenRect rect{ w->windowPos + ScreenCoordsXY{ widget->left, widget->top },
w->windowPos + ScreenCoordsXY{ widget->right, widget->bottom } };
ScreenRect rect{ w->windowPos + ScreenCoordsXY{ widget.left, widget.top },
w->windowPos + ScreenCoordsXY{ widget.right, widget.bottom } };
// Get the colour
uint8_t colour = w->colours[widget->colour];
uint8_t colour = w->colours[widget.colour];
gfx_fill_rect_inset(dpi, rect, colour, INSET_RECT_F_60);
WidgetText(dpi, w, widgetIndex);
}
static std::pair<rct_string_id, void*> widget_get_stringid_and_args(const rct_widget* widget)
static std::pair<rct_string_id, void*> widget_get_stringid_and_args(const rct_widget& widget)
{
auto stringId = widget->text;
auto stringId = widget.text;
void* formatArgs = gCommonFormatArgs;
if (widget->flags & WIDGET_FLAGS::TEXT_IS_STRING)
if (widget.flags & WIDGET_FLAGS::TEXT_IS_STRING)
{
if (widget->string == nullptr || widget->string[0] == '\0')
if (widget.string == nullptr || widget.string[0] == '\0')
{
stringId = STR_NONE;
formatArgs = nullptr;
@ -449,7 +450,7 @@ static std::pair<rct_string_id, void*> widget_get_stringid_and_args(const rct_wi
else
{
stringId = STR_STRING;
formatArgs = const_cast<void*>(reinterpret_cast<const void*>(&widget->string));
formatArgs = const_cast<void*>(reinterpret_cast<const void*>(&widget.string));
}
}
return std::make_pair(stringId, formatArgs);
@ -462,18 +463,18 @@ static std::pair<rct_string_id, void*> widget_get_stringid_and_args(const rct_wi
static void WidgetGroupboxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex)
{
// Get the widget
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
// Resolve the absolute ltrb
auto l = w->windowPos.x + widget->left + 5;
auto t = w->windowPos.y + widget->top;
auto l = w->windowPos.x + widget.left + 5;
auto t = w->windowPos.y + widget.top;
auto textRight = l;
// Text
auto [stringId, formatArgs] = widget_get_stringid_and_args(widget);
if (stringId != STR_NONE)
{
uint8_t colour = w->colours[widget->colour] & 0x7F;
uint8_t colour = w->colours[widget.colour] & 0x7F;
if (WidgetIsDisabled(w, widgetIndex))
colour |= COLOUR_FLAG_INSET;
@ -487,13 +488,13 @@ static void WidgetGroupboxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widget
// Border
// Resolve the absolute ltrb
l = w->windowPos.x + widget->left;
t = w->windowPos.y + widget->top + 4;
const auto r = w->windowPos.x + widget->right;
const auto b = w->windowPos.y + widget->bottom;
l = w->windowPos.x + widget.left;
t = w->windowPos.y + widget.top + 4;
const auto r = w->windowPos.x + widget.right;
const auto b = w->windowPos.y + widget.bottom;
// Get the colour
uint8_t colour = w->colours[widget->colour] & 0x7F;
uint8_t colour = w->colours[widget.colour] & 0x7F;
// Border left of text
gfx_fill_rect(dpi, { { l, t }, { l + 4, t } }, ColourMapA[colour].mid_dark);
@ -523,7 +524,7 @@ static void WidgetGroupboxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widget
static void WidgetCaptionDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex)
{
// Get the widget
rct_widget* widget = &w->widgets[widgetIndex];
const auto* widget = &w->widgets[widgetIndex];
// Resolve the absolute ltrb
auto topLeft = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
@ -571,11 +572,11 @@ static void WidgetCaptionDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgeti
static void WidgetCloseboxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex)
{
// Get the widget
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
// Resolve the absolute ltrb
auto topLeft = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
auto bottomRight = w->windowPos + ScreenCoordsXY{ widget->right, widget->bottom };
auto topLeft = w->windowPos + ScreenCoordsXY{ widget.left, widget.top };
auto bottomRight = w->windowPos + ScreenCoordsXY{ widget.right, widget.bottom };
// Check if the button is pressed down
uint8_t press = 0;
@ -585,20 +586,20 @@ static void WidgetCloseboxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widget
press |= INSET_RECT_FLAG_BORDER_INSET;
// Get the colour
uint8_t colour = w->colours[widget->colour];
uint8_t colour = w->colours[widget.colour];
// Draw the button
gfx_fill_rect_inset(dpi, { topLeft, bottomRight }, colour, press);
if (widget->text == STR_NONE)
if (widget.text == STR_NONE)
return;
topLeft = w->windowPos + ScreenCoordsXY{ widget->midX() - 1, std::max<int32_t>(widget->top, widget->midY() - 5) };
topLeft = w->windowPos + ScreenCoordsXY{ widget.midX() - 1, std::max<int32_t>(widget.top, widget.midY() - 5) };
if (WidgetIsDisabled(w, widgetIndex))
colour |= COLOUR_FLAG_INSET;
DrawTextEllipsised(dpi, topLeft, widget->width() - 2, widget->text, Formatter::Common(), { colour, TextAlignment::CENTRE });
DrawTextEllipsised(dpi, topLeft, widget.width() - 2, widget.text, Formatter::Common(), { colour, TextAlignment::CENTRE });
}
/**
@ -608,15 +609,15 @@ static void WidgetCloseboxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widget
static void WidgetCheckboxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex)
{
// Get the widget
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
// Resolve the absolute ltb
ScreenCoordsXY topLeft = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
ScreenCoordsXY bottomRight = w->windowPos + ScreenCoordsXY{ widget->right, widget->bottom };
ScreenCoordsXY topLeft = w->windowPos + ScreenCoordsXY{ widget.left, widget.top };
ScreenCoordsXY bottomRight = w->windowPos + ScreenCoordsXY{ widget.right, widget.bottom };
ScreenCoordsXY midLeft = { topLeft.x, (topLeft.y + bottomRight.y) / 2 };
// Get the colour
colour_t colour = w->colours[widget->colour];
colour_t colour = w->colours[widget.colour];
// checkbox
gfx_fill_rect_inset(dpi, { midLeft - ScreenCoordsXY{ 0, 5 }, midLeft + ScreenCoordsXY{ 9, 4 } }, colour, INSET_RECT_F_60);
@ -635,7 +636,7 @@ static void WidgetCheckboxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widget
}
// draw the text
if (widget->text == STR_NONE)
if (widget.text == STR_NONE)
return;
auto [stringId, formatArgs] = widget_get_stringid_and_args(widget);
@ -650,15 +651,15 @@ static void WidgetScrollDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetin
{
// Get the widget
int32_t scrollIndex = window_get_scroll_data_index(w, widgetIndex);
rct_widget* widget = &w->widgets[widgetIndex];
rct_scroll* scroll = &w->scrolls[scrollIndex];
const auto& widget = w->widgets[widgetIndex];
const auto& scroll = w->scrolls[scrollIndex];
// Resolve the absolute ltrb
ScreenCoordsXY topLeft = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
ScreenCoordsXY bottomRight = w->windowPos + ScreenCoordsXY{ widget->right, widget->bottom };
ScreenCoordsXY topLeft = w->windowPos + ScreenCoordsXY{ widget.left, widget.top };
ScreenCoordsXY bottomRight = w->windowPos + ScreenCoordsXY{ widget.right, widget.bottom };
// Get the colour
uint8_t colour = w->colours[widget->colour];
uint8_t colour = w->colours[widget.colour];
// Draw the border
gfx_fill_rect_inset(dpi, { topLeft, bottomRight }, colour, INSET_RECT_F_60);
@ -670,22 +671,22 @@ static void WidgetScrollDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetin
bottomRight.y--;
// Horizontal scrollbar
if (scroll->flags & HSCROLLBAR_VISIBLE)
if (scroll.flags & HSCROLLBAR_VISIBLE)
WidgetHScrollbarDraw(
dpi, scroll, topLeft.x, bottomRight.y - SCROLLBAR_WIDTH,
((scroll->flags & VSCROLLBAR_VISIBLE) ? bottomRight.x - (SCROLLBAR_WIDTH + 1) : bottomRight.x), bottomRight.y,
((scroll.flags & VSCROLLBAR_VISIBLE) ? bottomRight.x - (SCROLLBAR_WIDTH + 1) : bottomRight.x), bottomRight.y,
colour);
// Vertical scrollbar
if (scroll->flags & VSCROLLBAR_VISIBLE)
if (scroll.flags & VSCROLLBAR_VISIBLE)
WidgetVScrollbarDraw(
dpi, scroll, bottomRight.x - SCROLLBAR_WIDTH, topLeft.y, bottomRight.x,
((scroll->flags & HSCROLLBAR_VISIBLE) ? bottomRight.y - (SCROLLBAR_WIDTH + 1) : bottomRight.y), colour);
((scroll.flags & HSCROLLBAR_VISIBLE) ? bottomRight.y - (SCROLLBAR_WIDTH + 1) : bottomRight.y), colour);
// Contents
if (scroll->flags & HSCROLLBAR_VISIBLE)
if (scroll.flags & HSCROLLBAR_VISIBLE)
bottomRight.y -= (SCROLLBAR_WIDTH + 1);
if (scroll->flags & VSCROLLBAR_VISIBLE)
if (scroll.flags & VSCROLLBAR_VISIBLE)
bottomRight.x -= (SCROLLBAR_WIDTH + 1);
bottomRight.y++;
@ -701,8 +702,8 @@ static void WidgetScrollDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetin
int32_t cb = std::min<int32_t>(dpi->y + dpi->height, bottomRight.y);
// Set the respective dpi attributes
scroll_dpi.x = cl - topLeft.x + scroll->h_left;
scroll_dpi.y = ct - topLeft.y + scroll->v_top;
scroll_dpi.x = cl - topLeft.x + scroll.h_left;
scroll_dpi.y = ct - topLeft.y + scroll.v_top;
scroll_dpi.width = cr - cl;
scroll_dpi.height = cb - ct;
scroll_dpi.bits += cl - dpi->x;
@ -715,7 +716,7 @@ static void WidgetScrollDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetin
}
static void WidgetHScrollbarDraw(
rct_drawpixelinfo* dpi, rct_scroll* scroll, int32_t l, int32_t t, int32_t r, int32_t b, int32_t colour)
rct_drawpixelinfo* dpi, const rct_scroll& scroll, int32_t l, int32_t t, int32_t r, int32_t b, int32_t colour)
{
colour &= 0x7F;
// Trough
@ -728,7 +729,7 @@ static void WidgetHScrollbarDraw(
// Left button
{
uint8_t flags = (scroll->flags & HSCROLLBAR_LEFT_PRESSED) ? INSET_RECT_FLAG_BORDER_INSET : 0;
uint8_t flags = (scroll.flags & HSCROLLBAR_LEFT_PRESSED) ? INSET_RECT_FLAG_BORDER_INSET : 0;
gfx_fill_rect_inset(dpi, { { l, t }, { l + (SCROLLBAR_WIDTH - 1), b } }, colour, flags);
gfx_draw_string(dpi, { l + 1, t }, static_cast<const char*>(BlackLeftArrowString), {});
@ -736,16 +737,16 @@ static void WidgetHScrollbarDraw(
// Thumb
{
int16_t left = std::max(l + SCROLLBAR_WIDTH, l + scroll->h_thumb_left - 1);
int16_t right = std::min(r - SCROLLBAR_WIDTH, l + scroll->h_thumb_right - 1);
uint8_t flags = (scroll->flags & HSCROLLBAR_THUMB_PRESSED) ? INSET_RECT_FLAG_BORDER_INSET : 0;
int16_t left = std::max(l + SCROLLBAR_WIDTH, l + scroll.h_thumb_left - 1);
int16_t right = std::min(r - SCROLLBAR_WIDTH, l + scroll.h_thumb_right - 1);
uint8_t flags = (scroll.flags & HSCROLLBAR_THUMB_PRESSED) ? INSET_RECT_FLAG_BORDER_INSET : 0;
gfx_fill_rect_inset(dpi, { { left, t }, { right, b } }, colour, flags);
}
// Right button
{
uint8_t flags = (scroll->flags & HSCROLLBAR_RIGHT_PRESSED) ? INSET_RECT_FLAG_BORDER_INSET : 0;
uint8_t flags = (scroll.flags & HSCROLLBAR_RIGHT_PRESSED) ? INSET_RECT_FLAG_BORDER_INSET : 0;
gfx_fill_rect_inset(dpi, { { r - (SCROLLBAR_WIDTH - 1), t }, { r, b } }, colour, flags);
gfx_draw_string(dpi, { r - 6, t }, static_cast<const char*>(BlackRightArrowString), {});
@ -753,7 +754,7 @@ static void WidgetHScrollbarDraw(
}
static void WidgetVScrollbarDraw(
rct_drawpixelinfo* dpi, rct_scroll* scroll, int32_t l, int32_t t, int32_t r, int32_t b, int32_t colour)
rct_drawpixelinfo* dpi, const rct_scroll& scroll, int32_t l, int32_t t, int32_t r, int32_t b, int32_t colour)
{
colour &= 0x7F;
// Trough
@ -767,20 +768,20 @@ static void WidgetVScrollbarDraw(
// Up button
gfx_fill_rect_inset(
dpi, { { l, t }, { r, t + (SCROLLBAR_WIDTH - 1) } }, colour,
((scroll->flags & VSCROLLBAR_UP_PRESSED) ? INSET_RECT_FLAG_BORDER_INSET : 0));
((scroll.flags & VSCROLLBAR_UP_PRESSED) ? INSET_RECT_FLAG_BORDER_INSET : 0));
gfx_draw_string(dpi, { l + 1, t - 1 }, static_cast<const char*>(BlackUpArrowString), {});
// Thumb
gfx_fill_rect_inset(
dpi,
{ { l, std::max(t + SCROLLBAR_WIDTH, t + scroll->v_thumb_top - 1) },
{ r, std::min(b - SCROLLBAR_WIDTH, t + scroll->v_thumb_bottom - 1) } },
colour, ((scroll->flags & VSCROLLBAR_THUMB_PRESSED) ? INSET_RECT_FLAG_BORDER_INSET : 0));
{ { l, std::max(t + SCROLLBAR_WIDTH, t + scroll.v_thumb_top - 1) },
{ r, std::min(b - SCROLLBAR_WIDTH, t + scroll.v_thumb_bottom - 1) } },
colour, ((scroll.flags & VSCROLLBAR_THUMB_PRESSED) ? INSET_RECT_FLAG_BORDER_INSET : 0));
// Down button
gfx_fill_rect_inset(
dpi, { { l, b - (SCROLLBAR_WIDTH - 1) }, { r, b } }, colour,
((scroll->flags & VSCROLLBAR_DOWN_PRESSED) ? INSET_RECT_FLAG_BORDER_INSET : 0));
((scroll.flags & VSCROLLBAR_DOWN_PRESSED) ? INSET_RECT_FLAG_BORDER_INSET : 0));
gfx_draw_string(dpi, { l + 1, b - (SCROLLBAR_WIDTH - 1) }, static_cast<const char*>(BlackDownArrowString), {});
}
@ -791,33 +792,33 @@ static void WidgetVScrollbarDraw(
static void WidgetDrawImage(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetIndex)
{
// Get the widget
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
// Get the image
int32_t image = widget->image;
int32_t image = widget.image;
if (image == SPR_NONE)
return;
// Resolve the absolute ltrb
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget.left, widget.top };
// Get the colour
uint8_t colour = NOT_TRANSLUCENT(w->colours[widget->colour]);
uint8_t colour = NOT_TRANSLUCENT(w->colours[widget.colour]);
if (widget->type == WindowWidgetType::ColourBtn || widget->type == WindowWidgetType::TrnBtn
|| widget->type == WindowWidgetType::Tab)
if (widget.type == WindowWidgetType::ColourBtn || widget.type == WindowWidgetType::TrnBtn
|| widget.type == WindowWidgetType::Tab)
if (WidgetIsPressed(w, widgetIndex) || WidgetIsActiveTool(w, widgetIndex))
image++;
if (WidgetIsDisabled(w, widgetIndex))
{
// Draw greyed out (light border bottom right shadow)
colour = w->colours[widget->colour];
colour = w->colours[widget.colour];
colour = ColourMapA[NOT_TRANSLUCENT(colour)].lighter;
gfx_draw_sprite_solid(dpi, image, screenCoords + ScreenCoordsXY{ 1, 1 }, colour);
// Draw greyed out (dark)
colour = w->colours[widget->colour];
colour = w->colours[widget.colour];
colour = ColourMapA[NOT_TRANSLUCENT(colour)].mid_light;
gfx_draw_sprite_solid(dpi, image, screenCoords, colour);
}
@ -916,7 +917,7 @@ bool WidgetIsActiveTool(rct_window* w, rct_widgetindex widgetIndex)
* edi: widget
*/
void WidgetScrollGetPart(
rct_window* w, rct_widget* widget, const ScreenCoordsXY& screenCoords, ScreenCoordsXY& retScreenCoords,
rct_window* w, const rct_widget* widget, const ScreenCoordsXY& screenCoords, ScreenCoordsXY& retScreenCoords,
int32_t* output_scroll_area, int32_t* scroll_id)
{
*scroll_id = 0;
@ -928,14 +929,14 @@ void WidgetScrollGetPart(
}
}
if ((w->scrolls[*scroll_id].flags & HSCROLLBAR_VISIBLE)
&& screenCoords.y >= (w->windowPos.y + widget->bottom - (SCROLLBAR_WIDTH + 1)))
const auto& scroll = w->scrolls[*scroll_id];
if ((scroll.flags & HSCROLLBAR_VISIBLE) && screenCoords.y >= (w->windowPos.y + widget->bottom - (SCROLLBAR_WIDTH + 1)))
{
// horizontal scrollbar
int32_t rightOffset = 0;
int32_t iteratorLeft = widget->left + w->windowPos.x + SCROLLBAR_WIDTH;
int32_t iteratorRight = widget->right + w->windowPos.x - SCROLLBAR_WIDTH;
if (!(w->scrolls[*scroll_id].flags & VSCROLLBAR_VISIBLE))
if (!(scroll.flags & VSCROLLBAR_VISIBLE))
{
rightOffset = SCROLLBAR_WIDTH + 1;
}
@ -952,11 +953,11 @@ void WidgetScrollGetPart(
{
*output_scroll_area = SCROLL_PART_HSCROLLBAR_RIGHT;
}
else if (screenCoords.x < (widget->left + w->windowPos.x + w->scrolls[*scroll_id].h_thumb_left))
else if (screenCoords.x < (widget->left + w->windowPos.x + scroll.h_thumb_left))
{
*output_scroll_area = SCROLL_PART_HSCROLLBAR_LEFT_TROUGH;
}
else if (screenCoords.x > (widget->left + w->windowPos.x + w->scrolls[*scroll_id].h_thumb_right))
else if (screenCoords.x > (widget->left + w->windowPos.x + scroll.h_thumb_right))
{
*output_scroll_area = SCROLL_PART_HSCROLLBAR_RIGHT_TROUGH;
}
@ -965,15 +966,13 @@ void WidgetScrollGetPart(
*output_scroll_area = SCROLL_PART_HSCROLLBAR_THUMB;
}
}
else if (
(w->scrolls[*scroll_id].flags & VSCROLLBAR_VISIBLE)
&& (screenCoords.x >= w->windowPos.x + widget->right - (SCROLLBAR_WIDTH + 1)))
else if ((scroll.flags & VSCROLLBAR_VISIBLE) && (screenCoords.x >= w->windowPos.x + widget->right - (SCROLLBAR_WIDTH + 1)))
{
// vertical scrollbar
int32_t bottomOffset = 0;
int32_t iteratorTop = widget->top + w->windowPos.y + SCROLLBAR_WIDTH;
int32_t iteratorBottom = widget->bottom + w->windowPos.y;
if (w->scrolls[*scroll_id].flags & HSCROLLBAR_VISIBLE)
if (scroll.flags & HSCROLLBAR_VISIBLE)
{
bottomOffset = (SCROLLBAR_WIDTH + 1);
}
@ -990,11 +989,11 @@ void WidgetScrollGetPart(
{
*output_scroll_area = SCROLL_PART_VSCROLLBAR_BOTTOM;
}
else if (screenCoords.y < (widget->top + w->windowPos.y + w->scrolls[*scroll_id].v_thumb_top))
else if (screenCoords.y < (widget->top + w->windowPos.y + scroll.v_thumb_top))
{
*output_scroll_area = SCROLL_PART_VSCROLLBAR_TOP_TROUGH;
}
else if (screenCoords.y > (widget->top + w->windowPos.y + w->scrolls[*scroll_id].v_thumb_bottom))
else if (screenCoords.y > (widget->top + w->windowPos.y + scroll.v_thumb_bottom))
{
*output_scroll_area = SCROLL_PART_VSCROLLBAR_BOTTOM_TROUGH;
}
@ -1016,8 +1015,8 @@ void WidgetScrollGetPart(
}
else
{
retScreenCoords.x += w->scrolls[*scroll_id].h_left - 1;
retScreenCoords.y += w->scrolls[*scroll_id].v_top - 1;
retScreenCoords.x += scroll.h_left - 1;
retScreenCoords.y += scroll.v_top - 1;
}
}
}
@ -1086,14 +1085,14 @@ static void WidgetTextBoxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgeti
char wrapped_string[TEXT_INPUT_SIZE];
// Get the widget
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
// Resolve the absolute ltrb
ScreenCoordsXY topLeft{ w->windowPos + ScreenCoordsXY{ widget->left, widget->top } };
ScreenCoordsXY bottomRight{ w->windowPos + ScreenCoordsXY{ widget->right, widget->bottom } };
ScreenCoordsXY topLeft{ w->windowPos + ScreenCoordsXY{ widget.left, widget.top } };
ScreenCoordsXY bottomRight{ w->windowPos + ScreenCoordsXY{ widget.right, widget.bottom } };
// Get the colour
uint8_t colour = w->colours[widget->colour];
uint8_t colour = w->colours[widget.colour];
bool active = w->classification == gCurrentTextBox.window.classification && w->number == gCurrentTextBox.window.number
&& widgetIndex == gCurrentTextBox.widget_index;
@ -1102,13 +1101,13 @@ static void WidgetTextBoxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgeti
gfx_fill_rect_inset(dpi, { topLeft, bottomRight }, colour, INSET_RECT_F_60);
// Figure out where the text should be positioned vertically.
topLeft.y = w->windowPos.y + widget->textTop();
topLeft.y = w->windowPos.y + widget.textTop();
if (!active || gTextInput == nullptr)
{
if (w->widgets[widgetIndex].text != 0)
if (widget.text != 0)
{
safe_strcpy(wrapped_string, w->widgets[widgetIndex].string, 512);
safe_strcpy(wrapped_string, widget.string, 512);
gfx_wrap_string(wrapped_string, bottomRight.x - topLeft.x - 5, FontSpriteBase::MEDIUM, &no_lines);
gfx_draw_string_no_formatting(
dpi, { topLeft.x + 2, topLeft.y }, wrapped_string, { w->colours[1], FontSpriteBase::MEDIUM });
@ -1144,7 +1143,7 @@ static void WidgetTextBoxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgeti
if (gTextBoxFrameNo <= 15)
{
colour = ColourMapA[w->colours[1]].mid_light;
auto y = topLeft.y + (widget->height() - 1);
auto y = topLeft.y + (widget.height() - 1);
gfx_fill_rect(dpi, { { cur_x, y }, { cur_x + width, y } }, colour + 5);
}
}

View File

@ -13,6 +13,7 @@
#include <SDL.h>
#include <algorithm>
#include <openrct2-ui/windows/Window.h>
#include <openrct2/Context.h>
#include <openrct2/Input.h>
#include <openrct2/OpenRCT2.h>
@ -356,25 +357,25 @@ static rct_widget* WindowGetScrollWidget(rct_window* w, int32_t scrollIndex)
*/
static void WindowScrollWheelInput(rct_window* w, int32_t scrollIndex, int32_t wheel)
{
rct_scroll* scroll = &w->scrolls[scrollIndex];
auto& scroll = w->scrolls[scrollIndex];
rct_widget* widget = WindowGetScrollWidget(w, scrollIndex);
rct_widgetindex widgetIndex = WindowGetWidgetIndex(w, widget);
if (scroll->flags & VSCROLLBAR_VISIBLE)
if (scroll.flags & VSCROLLBAR_VISIBLE)
{
int32_t size = widget->height() - 1;
if (scroll->flags & HSCROLLBAR_VISIBLE)
if (scroll.flags & HSCROLLBAR_VISIBLE)
size -= 11;
size = std::max(0, scroll->v_bottom - size);
scroll->v_top = std::min(std::max(0, scroll->v_top + wheel), size);
size = std::max(0, scroll.v_bottom - size);
scroll.v_top = std::min(std::max(0, scroll.v_top + wheel), size);
}
else
{
int32_t size = widget->width() - 1;
if (scroll->flags & VSCROLLBAR_VISIBLE)
if (scroll.flags & VSCROLLBAR_VISIBLE)
size -= 11;
size = std::max(0, scroll->h_right - size);
scroll->h_left = std::min(std::max(0, scroll->h_left + wheel), size);
size = std::max(0, scroll.h_right - size);
scroll.h_left = std::min(std::max(0, scroll.h_left + wheel), size);
}
WidgetScrollUpdateThumbs(w, widgetIndex);
@ -394,8 +395,8 @@ static int32_t WindowWheelInput(rct_window* w, int32_t wheel)
continue;
// Originally always checked first scroll view, bug maybe?
rct_scroll* scroll = &w->scrolls[i];
if (scroll->flags & (HSCROLLBAR_VISIBLE | VSCROLLBAR_VISIBLE))
const auto& scroll = w->scrolls[i];
if (scroll.flags & (HSCROLLBAR_VISIBLE | VSCROLLBAR_VISIBLE))
{
WindowScrollWheelInput(w, i, wheel);
return 1;
@ -538,12 +539,12 @@ void WindowAllWheelInput()
rct_widgetindex widgetIndex = window_find_widget_from_point(w, cursorState->position);
if (widgetIndex != -1)
{
rct_widget* widget = &w->widgets[widgetIndex];
if (widget->type == WindowWidgetType::Scroll)
const auto& widget = w->widgets[widgetIndex];
if (widget.type == WindowWidgetType::Scroll)
{
int32_t scrollIndex = WindowGetScrollIndex(w, widgetIndex);
rct_scroll* scroll = &w->scrolls[scrollIndex];
if (scroll->flags & (HSCROLLBAR_VISIBLE | VSCROLLBAR_VISIBLE))
const auto& scroll = w->scrolls[scrollIndex];
if (scroll.flags & (HSCROLLBAR_VISIBLE | VSCROLLBAR_VISIBLE))
{
WindowScrollWheelInput(w, WindowGetScrollIndex(w, widgetIndex), pixel_scroll);
return;
@ -577,7 +578,6 @@ void ApplyScreenSaverLockSetting()
void WindowInitScrollWidgets(rct_window* w)
{
rct_widget* widget;
rct_scroll* scroll;
int32_t widget_index, scroll_index;
int32_t width, height;
@ -591,20 +591,20 @@ void WindowInitScrollWidgets(rct_window* w)
continue;
}
scroll = &w->scrolls[scroll_index];
scroll->flags = 0;
auto& scroll = w->scrolls[scroll_index];
scroll.flags = 0;
width = 0;
height = 0;
window_get_scroll_size(w, scroll_index, &width, &height);
scroll->h_left = 0;
scroll->h_right = width + 1;
scroll->v_top = 0;
scroll->v_bottom = height + 1;
scroll.h_left = 0;
scroll.h_right = width + 1;
scroll.v_top = 0;
scroll.v_bottom = height + 1;
if (widget->content & SCROLL_HORIZONTAL)
scroll->flags |= HSCROLLBAR_VISIBLE;
scroll.flags |= HSCROLLBAR_VISIBLE;
if (widget->content & SCROLL_VERTICAL)
scroll->flags |= VSCROLLBAR_VISIBLE;
scroll.flags |= VSCROLLBAR_VISIBLE;
WidgetScrollUpdateThumbs(w, widget_index);
@ -751,3 +751,10 @@ void Window::Close()
{
window_close(this);
}
void Window::TextInputOpen(
rct_widgetindex callWidget, rct_string_id title, rct_string_id description, const Formatter& descriptionArgs,
rct_string_id existingText, uintptr_t existingArgs, int32_t maxLength)
{
window_text_input_open(this, callWidget, title, description, descriptionArgs, existingText, existingArgs, maxLength);
}

View File

@ -26,6 +26,9 @@ struct Window : rct_window
void SetCheckboxValue(rct_widgetindex widgetIndex, bool value);
void DrawWidgets(rct_drawpixelinfo& dpi);
void Close();
void TextInputOpen(
rct_widgetindex callWidget, rct_string_id title, rct_string_id description, const Formatter& descriptionArgs,
rct_string_id existingText, uintptr_t existingArgs, int32_t maxLength);
};
void WindowAllWheelInput();

View File

@ -1,5 +1,5 @@
/*****************************************************************************
* Copyright (c) 2014-2020 OpenRCT2 developers
* Copyright (c) 2014-2021 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
@ -16,8 +16,8 @@
#include <openrct2/world/Park.h>
#include <openrct2/world/Scenery.h>
// clang-format off
enum WINDOW_CLEAR_SCENERY_WIDGET_IDX {
enum WINDOW_CLEAR_SCENERY_WIDGET_IDX
{
WIDX_BACKGROUND,
WIDX_TITLE,
WIDX_CLOSE,
@ -28,213 +28,182 @@ enum WINDOW_CLEAR_SCENERY_WIDGET_IDX {
WIDX_LARGE_SCENERY,
WIDX_FOOTPATH
};
// clang-format on
static constexpr const rct_string_id WINDOW_TITLE = STR_CLEAR_SCENERY;
static constexpr const int32_t WW = 98;
static constexpr const int32_t WH = 94;
static constexpr ScreenSize CLEAR_SCENERY_BUTTON = { 24, 24 };
static rct_widget window_clear_scenery_widgets[] = {
WINDOW_SHIM(WINDOW_TITLE, WW, WH),
MakeWidget ({27, 17}, {44, 32}, WindowWidgetType::ImgBtn, WindowColour::Primary , SPR_LAND_TOOL_SIZE_0, STR_NONE), // preview box
MakeRemapWidget({28, 18}, {16, 16}, WindowWidgetType::TrnBtn, WindowColour::Secondary, SPR_LAND_TOOL_DECREASE, STR_ADJUST_SMALLER_LAND_TIP), // decrement size
MakeRemapWidget({54, 32}, {16, 16}, WindowWidgetType::TrnBtn, WindowColour::Secondary, SPR_LAND_TOOL_INCREASE, STR_ADJUST_LARGER_LAND_TIP), // increment size
MakeRemapWidget({ 7, 53}, {24, 24}, WindowWidgetType::FlatBtn, WindowColour::Secondary, SPR_G2_BUTTON_TREES, STR_CLEAR_SCENERY_REMOVE_SMALL_SCENERY_TIP), // small scenery
MakeRemapWidget({37, 53}, {24, 24}, WindowWidgetType::FlatBtn, WindowColour::Secondary, SPR_G2_BUTTON_LARGE_SCENERY, STR_CLEAR_SCENERY_REMOVE_LARGE_SCENERY_TIP), // large scenery
MakeRemapWidget({67, 53}, {24, 24}, WindowWidgetType::FlatBtn, WindowColour::Secondary, SPR_G2_BUTTON_FOOTPATH, STR_CLEAR_SCENERY_REMOVE_FOOTPATHS_TIP), // footpaths
MakeWidget(
{ 27, 17 }, { 44, 32 }, WindowWidgetType::ImgBtn, WindowColour::Primary, SPR_LAND_TOOL_SIZE_0, STR_NONE), // preview box
MakeRemapWidget(
{ 28, 18 }, { 16, 16 }, WindowWidgetType::TrnBtn, WindowColour::Secondary, SPR_LAND_TOOL_DECREASE,
STR_ADJUST_SMALLER_LAND_TIP), // decrement size
MakeRemapWidget(
{ 54, 32 }, { 16, 16 }, WindowWidgetType::TrnBtn, WindowColour::Secondary, SPR_LAND_TOOL_INCREASE,
STR_ADJUST_LARGER_LAND_TIP), // increment size
MakeRemapWidget(
{ 7, 53 }, CLEAR_SCENERY_BUTTON, WindowWidgetType::FlatBtn, WindowColour::Secondary, SPR_G2_BUTTON_TREES,
STR_CLEAR_SCENERY_REMOVE_SMALL_SCENERY_TIP), // small scenery
MakeRemapWidget(
{ 37, 53 }, CLEAR_SCENERY_BUTTON, WindowWidgetType::FlatBtn, WindowColour::Secondary, SPR_G2_BUTTON_LARGE_SCENERY,
STR_CLEAR_SCENERY_REMOVE_LARGE_SCENERY_TIP), // large scenery
MakeRemapWidget(
{ 67, 53 }, CLEAR_SCENERY_BUTTON, WindowWidgetType::FlatBtn, WindowColour::Secondary, SPR_G2_BUTTON_FOOTPATH,
STR_CLEAR_SCENERY_REMOVE_FOOTPATHS_TIP), // footpaths
WIDGETS_END,
};
static void window_clear_scenery_close(rct_window *w);
static void window_clear_scenery_mouseup(rct_window *w, rct_widgetindex widgetIndex);
static void window_clear_scenery_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget);
static void window_clear_scenery_update(rct_window *w);
static void window_clear_scenery_invalidate(rct_window *w);
static void window_clear_scenery_paint(rct_window *w, rct_drawpixelinfo *dpi);
static void window_clear_scenery_textinput(rct_window *w, rct_widgetindex widgetIndex, char *text);
static void window_clear_scenery_inputsize(rct_window *w);
static rct_window_event_list window_clear_scenery_events([](auto& events)
class CleanSceneryWindow final : public Window
{
events.close = &window_clear_scenery_close;
events.mouse_up = &window_clear_scenery_mouseup;
events.mouse_down = &window_clear_scenery_mousedown;
events.update = &window_clear_scenery_update;
events.text_input = &window_clear_scenery_textinput;
events.invalidate = &window_clear_scenery_invalidate;
events.paint = &window_clear_scenery_paint;
});
// clang-format on
public:
void OnOpen() override
{
widgets = window_clear_scenery_widgets;
enabled_widgets = (1ULL << WIDX_CLOSE) | (1ULL << WIDX_INCREMENT) | (1ULL << WIDX_DECREMENT) | (1ULL << WIDX_PREVIEW)
| (1ULL << WIDX_SMALL_SCENERY) | (1ULL << WIDX_LARGE_SCENERY) | (1ULL << WIDX_FOOTPATH);
hold_down_widgets = (1ULL << WIDX_INCREMENT) | (1ULL << WIDX_DECREMENT);
WindowInitScrollWidgets(this);
window_push_others_below(this);
gLandToolSize = 2;
gClearSceneryCost = MONEY64_UNDEFINED;
gClearSmallScenery = true;
gClearLargeScenery = false;
gClearFootpath = false;
}
void OnClose() override
{
if (clear_scenery_tool_is_active())
tool_cancel();
}
void OnMouseUp(const rct_widgetindex widgetIndex) override
{
switch (widgetIndex)
{
case WIDX_CLOSE:
Close();
break;
case WIDX_PREVIEW:
{
Formatter ft;
ft.Add<int16_t>(MINIMUM_TOOL_SIZE);
ft.Add<int16_t>(MAXIMUM_TOOL_SIZE);
TextInputOpen(WIDX_PREVIEW, STR_SELECTION_SIZE, STR_ENTER_SELECTION_SIZE, ft, STR_NONE, STR_NONE, 3);
break;
}
case WIDX_SMALL_SCENERY:
gClearSmallScenery ^= 1;
Invalidate();
break;
case WIDX_LARGE_SCENERY:
gClearLargeScenery ^= 1;
Invalidate();
break;
case WIDX_FOOTPATH:
gClearFootpath ^= 1;
Invalidate();
break;
}
}
void OnMouseDown(const rct_widgetindex widgetIndex) override
{
switch (widgetIndex)
{
case WIDX_DECREMENT:
// Decrement land tool size, if it stays within the limit
gLandToolSize = std::max(MINIMUM_TOOL_SIZE, gLandToolSize - 1);
// Invalidate the window
Invalidate();
break;
case WIDX_INCREMENT:
// Increment land tool size, if it stays within the limit
gLandToolSize = std::min(MAXIMUM_TOOL_SIZE, gLandToolSize + 1);
// Invalidate the window
Invalidate();
break;
}
}
void OnTextInput(const rct_widgetindex widgetIndex, const std::string_view text) override
{
if (widgetIndex != WIDX_PREVIEW || text.empty())
return;
char* end;
int32_t size = strtol(std::string(text).c_str(), &end, 10);
if (*end == '\0')
{
size = std::clamp(size, MINIMUM_TOOL_SIZE, MAXIMUM_TOOL_SIZE);
gLandToolSize = size;
Invalidate();
}
}
void OnUpdate() override
{
frame_no++;
// Close window if another tool is open
if (!clear_scenery_tool_is_active())
Close();
}
void Invalidate()
{
// Set the preview image button to be pressed down
pressed_widgets = (1ULL << WIDX_PREVIEW) | (gClearSmallScenery ? (1ULL << WIDX_SMALL_SCENERY) : 0)
| (gClearLargeScenery ? (1ULL << WIDX_LARGE_SCENERY) : 0) | (gClearFootpath ? (1ULL << WIDX_FOOTPATH) : 0);
// Update the preview image (for tool sizes up to 7)
window_clear_scenery_widgets[WIDX_PREVIEW].image = LandTool::SizeToSpriteIndex(gLandToolSize);
}
void OnDraw(rct_drawpixelinfo& dpi) override
{
DrawWidgets(dpi);
// Draw number for tool sizes bigger than 7
ScreenCoordsXY screenCoords = { windowPos.x + window_clear_scenery_widgets[WIDX_PREVIEW].midX(),
windowPos.y + window_clear_scenery_widgets[WIDX_PREVIEW].midY() };
if (gLandToolSize > MAX_TOOL_SIZE_WITH_SPRITE)
{
auto ft = Formatter();
ft.Add<uint16_t>(gLandToolSize);
DrawTextBasic(&dpi, screenCoords - ScreenCoordsXY{ 0, 2 }, STR_LAND_TOOL_SIZE_VALUE, ft, { TextAlignment::CENTRE });
}
// Draw cost amount
if (gClearSceneryCost != MONEY64_UNDEFINED && gClearSceneryCost != 0 && !(gParkFlags & PARK_FLAGS_NO_MONEY))
{
auto ft = Formatter();
ft.Add<money64>(gClearSceneryCost);
screenCoords.x = window_clear_scenery_widgets[WIDX_PREVIEW].midX() + windowPos.x;
screenCoords.y = window_clear_scenery_widgets[WIDX_PREVIEW].bottom + windowPos.y + 5 + 27;
DrawTextBasic(&dpi, screenCoords, STR_COST_AMOUNT, ft, { TextAlignment::CENTRE });
}
}
};
/**
*
* rct2: 0x0068E0A7
*/
rct_window* window_clear_scenery_open()
{
rct_window* window;
auto* w = static_cast<CleanSceneryWindow*>(window_bring_to_front_by_class(WC_CLEAR_SCENERY));
// Check if window is already open
window = window_find_by_class(WC_CLEAR_SCENERY);
if (window != nullptr)
return window;
if (w != nullptr)
return w;
window = WindowCreate(
ScreenCoordsXY(context_get_width() - WW, 29), WW, WH, &window_clear_scenery_events, WC_CLEAR_SCENERY, 0);
window->widgets = window_clear_scenery_widgets;
window->enabled_widgets = (1ULL << WIDX_CLOSE) | (1ULL << WIDX_INCREMENT) | (1ULL << WIDX_DECREMENT)
| (1ULL << WIDX_PREVIEW) | (1ULL << WIDX_SMALL_SCENERY) | (1ULL << WIDX_LARGE_SCENERY) | (1ULL << WIDX_FOOTPATH);
window->hold_down_widgets = (1ULL << WIDX_INCREMENT) | (1ULL << WIDX_DECREMENT);
WindowInitScrollWidgets(window);
window_push_others_below(window);
w = WindowCreate<CleanSceneryWindow>(WC_CLEAR_SCENERY, WW, WH, 0);
gLandToolSize = 2;
gClearSceneryCost = MONEY64_UNDEFINED;
if (w != nullptr)
return w;
gClearSmallScenery = true;
gClearLargeScenery = false;
gClearFootpath = false;
return window;
}
/**
*
* rct2: 0x006E6B65
*/
static void window_clear_scenery_close([[maybe_unused]] rct_window* w)
{
// If the tool wasn't changed, turn tool off
if (clear_scenery_tool_is_active())
tool_cancel();
}
/**
*
* rct2: 0x0068E185
*/
static void window_clear_scenery_mouseup(rct_window* w, rct_widgetindex widgetIndex)
{
switch (widgetIndex)
{
case WIDX_CLOSE:
window_close(w);
break;
case WIDX_PREVIEW:
window_clear_scenery_inputsize(w);
break;
case WIDX_SMALL_SCENERY:
gClearSmallScenery ^= 1;
w->Invalidate();
break;
case WIDX_LARGE_SCENERY:
gClearLargeScenery ^= 1;
w->Invalidate();
break;
case WIDX_FOOTPATH:
gClearFootpath ^= 1;
w->Invalidate();
break;
}
}
static void window_clear_scenery_mousedown(rct_window* w, rct_widgetindex widgetIndex, [[maybe_unused]] rct_widget* widget)
{
switch (widgetIndex)
{
case WIDX_DECREMENT:
// Decrement land tool size, if it stays within the limit
gLandToolSize = std::max(MINIMUM_TOOL_SIZE, gLandToolSize - 1);
// Invalidate the window
w->Invalidate();
break;
case WIDX_INCREMENT:
// Increment land tool size, if it stays within the limit
gLandToolSize = std::min(MAXIMUM_TOOL_SIZE, gLandToolSize + 1);
// Invalidate the window
w->Invalidate();
break;
}
}
static void window_clear_scenery_textinput(rct_window* w, rct_widgetindex widgetIndex, char* text)
{
int32_t size;
char* end;
if (widgetIndex != WIDX_PREVIEW || text == nullptr)
return;
size = strtol(text, &end, 10);
if (*end == '\0')
{
size = std::max(MINIMUM_TOOL_SIZE, size);
size = std::min(MAXIMUM_TOOL_SIZE, size);
gLandToolSize = size;
w->Invalidate();
}
}
static void window_clear_scenery_inputsize(rct_window* w)
{
Formatter ft;
ft.Add<int16_t>(MINIMUM_TOOL_SIZE);
ft.Add<int16_t>(MAXIMUM_TOOL_SIZE);
window_text_input_open(w, WIDX_PREVIEW, STR_SELECTION_SIZE, STR_ENTER_SELECTION_SIZE, ft, STR_NONE, STR_NONE, 3);
}
/**
*
* rct2: 0x0068E205
*/
static void window_clear_scenery_update(rct_window* w)
{
w->frame_no++;
// Close window if another tool is open
if (!clear_scenery_tool_is_active())
window_close(w);
}
/**
*
* rct2: 0x0068E115
*/
static void window_clear_scenery_invalidate(rct_window* w)
{
// Set the preview image button to be pressed down
w->pressed_widgets = (1ULL << WIDX_PREVIEW) | (gClearSmallScenery ? (1ULL << WIDX_SMALL_SCENERY) : 0)
| (gClearLargeScenery ? (1ULL << WIDX_LARGE_SCENERY) : 0) | (gClearFootpath ? (1ULL << WIDX_FOOTPATH) : 0);
// Update the preview image (for tool sizes up to 7)
window_clear_scenery_widgets[WIDX_PREVIEW].image = LandTool::SizeToSpriteIndex(gLandToolSize);
}
/**
*
* rct2: 0x0068E130
*/
static void window_clear_scenery_paint(rct_window* w, rct_drawpixelinfo* dpi)
{
WindowDrawWidgets(w, dpi);
// Draw number for tool sizes bigger than 7
ScreenCoordsXY screenCoords = { w->windowPos.x + window_clear_scenery_widgets[WIDX_PREVIEW].midX(),
w->windowPos.y + window_clear_scenery_widgets[WIDX_PREVIEW].midY() };
if (gLandToolSize > MAX_TOOL_SIZE_WITH_SPRITE)
{
auto ft = Formatter();
ft.Add<uint16_t>(gLandToolSize);
DrawTextBasic(dpi, screenCoords - ScreenCoordsXY{ 0, 2 }, STR_LAND_TOOL_SIZE_VALUE, ft, { TextAlignment::CENTRE });
}
// Draw cost amount
if (gClearSceneryCost != MONEY64_UNDEFINED && gClearSceneryCost != 0 && !(gParkFlags & PARK_FLAGS_NO_MONEY))
{
auto ft = Formatter();
ft.Add<money64>(gClearSceneryCost);
screenCoords.x = window_clear_scenery_widgets[WIDX_PREVIEW].midX() + w->windowPos.x;
screenCoords.y = window_clear_scenery_widgets[WIDX_PREVIEW].bottom + w->windowPos.y + 5 + 27;
DrawTextBasic(dpi, screenCoords, STR_COST_AMOUNT, ft, { TextAlignment::CENTRE });
}
return nullptr;
}

View File

@ -474,9 +474,8 @@ static void window_editor_scenario_options_financial_resize(rct_window* w)
static void window_editor_scenario_options_show_climate_dropdown(rct_window* w)
{
int32_t i;
rct_widget* dropdownWidget;
dropdownWidget = &w->widgets[WIDX_CLIMATE];
const auto& dropdownWidget = w->widgets[WIDX_CLIMATE];
for (i = 0; i < static_cast<uint8_t>(ClimateType::Count); i++)
{
@ -484,8 +483,8 @@ static void window_editor_scenario_options_show_climate_dropdown(rct_window* w)
gDropdownItemsArgs[i] = ClimateNames[i];
}
WindowDropdownShowTextCustomWidth(
{ w->windowPos.x + dropdownWidget->left, w->windowPos.y + dropdownWidget->top }, dropdownWidget->height() + 1,
w->colours[1], 0, Dropdown::Flag::StayOpen, static_cast<uint8_t>(ClimateType::Count), dropdownWidget->width() - 3);
{ w->windowPos.x + dropdownWidget.left, w->windowPos.y + dropdownWidget.top }, dropdownWidget.height() + 1,
w->colours[1], 0, Dropdown::Flag::StayOpen, static_cast<uint8_t>(ClimateType::Count), dropdownWidget.width() - 3);
Dropdown::SetChecked(static_cast<uint8_t>(gClimate), true);
}
@ -683,49 +682,49 @@ static void window_editor_scenario_options_financial_paint(rct_window* w, rct_dr
WindowDrawWidgets(w, dpi);
window_editor_scenario_options_draw_tab_images(w, dpi);
if (w->widgets[WIDX_INITIAL_CASH].type != WindowWidgetType::Empty)
const auto& initialCashWidget = w->widgets[WIDX_INITIAL_CASH];
if (initialCashWidget.type != WindowWidgetType::Empty)
{
screenCoords = w->windowPos + ScreenCoordsXY{ 8, w->widgets[WIDX_INITIAL_CASH].top };
screenCoords = w->windowPos + ScreenCoordsXY{ 8, initialCashWidget.top };
DrawTextBasic(dpi, screenCoords, STR_INIT_CASH_LABEL);
screenCoords = w->windowPos
+ ScreenCoordsXY{ w->widgets[WIDX_INITIAL_CASH].left + 1, w->widgets[WIDX_INITIAL_CASH].top };
screenCoords = w->windowPos + ScreenCoordsXY{ initialCashWidget.left + 1, initialCashWidget.top };
auto ft = Formatter();
ft.Add<money64>(gInitialCash);
DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft);
}
if (w->widgets[WIDX_INITIAL_LOAN].type != WindowWidgetType::Empty)
const auto& initialLoanWidget = w->widgets[WIDX_INITIAL_LOAN];
if (initialLoanWidget.type != WindowWidgetType::Empty)
{
screenCoords = w->windowPos + ScreenCoordsXY{ 8, w->widgets[WIDX_INITIAL_LOAN].top };
screenCoords = w->windowPos + ScreenCoordsXY{ 8, initialLoanWidget.top };
DrawTextBasic(dpi, screenCoords, STR_INIT_LOAN_LABEL);
screenCoords = w->windowPos
+ ScreenCoordsXY{ w->widgets[WIDX_INITIAL_LOAN].left + 1, w->widgets[WIDX_INITIAL_LOAN].top };
screenCoords = w->windowPos + ScreenCoordsXY{ initialLoanWidget.left + 1, initialLoanWidget.top };
auto ft = Formatter();
ft.Add<money64>(gBankLoan);
DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft);
}
if (w->widgets[WIDX_MAXIMUM_LOAN].type != WindowWidgetType::Empty)
const auto& maximumLoanWidget = w->widgets[WIDX_MAXIMUM_LOAN];
if (maximumLoanWidget.type != WindowWidgetType::Empty)
{
screenCoords = w->windowPos + ScreenCoordsXY{ 8, w->widgets[WIDX_MAXIMUM_LOAN].top };
screenCoords = w->windowPos + ScreenCoordsXY{ 8, maximumLoanWidget.top };
DrawTextBasic(dpi, screenCoords, STR_MAX_LOAN_LABEL);
screenCoords = w->windowPos
+ ScreenCoordsXY{ w->widgets[WIDX_MAXIMUM_LOAN].left + 1, w->widgets[WIDX_MAXIMUM_LOAN].top };
screenCoords = w->windowPos + ScreenCoordsXY{ maximumLoanWidget.left + 1, maximumLoanWidget.top };
auto ft = Formatter();
ft.Add<money64>(gMaxBankLoan);
DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft);
}
if (w->widgets[WIDX_INTEREST_RATE].type != WindowWidgetType::Empty)
const auto& interestRateWidget = w->widgets[WIDX_INTEREST_RATE];
if (interestRateWidget.type != WindowWidgetType::Empty)
{
screenCoords = w->windowPos + ScreenCoordsXY{ 8, w->widgets[WIDX_INTEREST_RATE].top };
screenCoords = w->windowPos + ScreenCoordsXY{ 8, interestRateWidget.top };
DrawTextBasic(dpi, screenCoords, STR_INTEREST_RATE_LABEL);
screenCoords = w->windowPos
+ ScreenCoordsXY{ w->widgets[WIDX_INTEREST_RATE].left + 1, w->widgets[WIDX_INTEREST_RATE].top };
screenCoords = w->windowPos + ScreenCoordsXY{ interestRateWidget.left + 1, interestRateWidget.top };
auto ft = Formatter();
ft.Add<int16_t>(std::clamp<int16_t>(static_cast<int16_t>(gBankLoanInterestRate), INT16_MIN, INT16_MAX));
@ -967,49 +966,49 @@ static void window_editor_scenario_options_guests_paint(rct_window* w, rct_drawp
WindowDrawWidgets(w, dpi);
window_editor_scenario_options_draw_tab_images(w, dpi);
if (w->widgets[WIDX_CASH_PER_GUEST].type != WindowWidgetType::Empty)
const auto& cashPerGuestWidget = w->widgets[WIDX_CASH_PER_GUEST];
if (cashPerGuestWidget.type != WindowWidgetType::Empty)
{
// Cash per guest label
screenCoords = w->windowPos + ScreenCoordsXY{ 8, w->widgets[WIDX_CASH_PER_GUEST].top };
screenCoords = w->windowPos + ScreenCoordsXY{ 8, cashPerGuestWidget.top };
DrawTextBasic(dpi, screenCoords, STR_CASH_PER_GUEST_LABEL);
// Cash per guest value
screenCoords = w->windowPos
+ ScreenCoordsXY{ w->widgets[WIDX_CASH_PER_GUEST].left + 1, w->widgets[WIDX_CASH_PER_GUEST].top };
screenCoords = w->windowPos + ScreenCoordsXY{ cashPerGuestWidget.left + 1, cashPerGuestWidget.top };
auto ft = Formatter();
ft.Add<money64>(gGuestInitialCash);
DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft);
}
// Guest initial happiness label
screenCoords = w->windowPos + ScreenCoordsXY{ 8, w->widgets[WIDX_GUEST_INITIAL_HAPPINESS].top };
const auto& initialHappinessWidget = w->widgets[WIDX_GUEST_INITIAL_HAPPINESS];
screenCoords = w->windowPos + ScreenCoordsXY{ 8, initialHappinessWidget.top };
DrawTextBasic(dpi, screenCoords, STR_GUEST_INIT_HAPPINESS);
// Guest initial happiness value
screenCoords = w->windowPos
+ ScreenCoordsXY{ w->widgets[WIDX_GUEST_INITIAL_HAPPINESS].left + 1, w->widgets[WIDX_GUEST_INITIAL_HAPPINESS].top };
screenCoords = w->windowPos + ScreenCoordsXY{ initialHappinessWidget.left + 1, initialHappinessWidget.top };
auto ft = Formatter();
ft.Add<uint16_t>((gGuestInitialHappiness * 100) / 255);
DrawTextBasic(dpi, screenCoords, STR_PERCENT_FORMAT_LABEL, ft);
// Guest initial hunger label
screenCoords = w->windowPos + ScreenCoordsXY{ 8, w->widgets[WIDX_GUEST_INITIAL_HUNGER].top };
const auto& initialHungerWidget = w->widgets[WIDX_GUEST_INITIAL_HUNGER];
screenCoords = w->windowPos + ScreenCoordsXY{ 8, initialHungerWidget.top };
DrawTextBasic(dpi, screenCoords, STR_GUEST_INIT_HUNGER);
// Guest initial hunger value
screenCoords = w->windowPos
+ ScreenCoordsXY{ w->widgets[WIDX_GUEST_INITIAL_HUNGER].left + 1, w->widgets[WIDX_GUEST_INITIAL_HUNGER].top };
screenCoords = w->windowPos + ScreenCoordsXY{ initialHungerWidget.left + 1, initialHungerWidget.top };
ft = Formatter();
ft.Add<uint16_t>(((255 - gGuestInitialHunger) * 100) / 255);
DrawTextBasic(dpi, screenCoords, STR_PERCENT_FORMAT_LABEL, ft);
// Guest initial thirst label
screenCoords = w->windowPos + ScreenCoordsXY{ 8, w->widgets[WIDX_GUEST_INITIAL_THIRST].top };
const auto& initialThirstWidget = w->widgets[WIDX_GUEST_INITIAL_THIRST];
screenCoords = w->windowPos + ScreenCoordsXY{ 8, initialThirstWidget.top };
DrawTextBasic(dpi, screenCoords, STR_GUEST_INIT_THIRST);
// Guest initial thirst value
screenCoords = w->windowPos
+ ScreenCoordsXY{ w->widgets[WIDX_GUEST_INITIAL_THIRST].left + 1, w->widgets[WIDX_GUEST_INITIAL_THIRST].top };
screenCoords = w->windowPos + ScreenCoordsXY{ initialThirstWidget.left + 1, initialThirstWidget.top };
ft = Formatter();
ft.Add<uint16_t>(((255 - gGuestInitialThirst) * 100) / 255);
DrawTextBasic(dpi, screenCoords, STR_PERCENT_FORMAT_LABEL, ft);
@ -1331,39 +1330,39 @@ static void window_editor_scenario_options_park_paint(rct_window* w, rct_drawpix
WindowDrawWidgets(w, dpi);
window_editor_scenario_options_draw_tab_images(w, dpi);
if (w->widgets[WIDX_LAND_COST].type != WindowWidgetType::Empty)
const auto& landCostWidget = w->widgets[WIDX_LAND_COST];
if (landCostWidget.type != WindowWidgetType::Empty)
{
// Cost to buy land label
screenCoords = w->windowPos + ScreenCoordsXY{ 8, w->widgets[WIDX_LAND_COST].top };
screenCoords = w->windowPos + ScreenCoordsXY{ 8, landCostWidget.top };
DrawTextBasic(dpi, screenCoords, STR_LAND_COST_LABEL);
// Cost to buy land value
screenCoords = w->windowPos + ScreenCoordsXY{ w->widgets[WIDX_LAND_COST].left + 1, w->widgets[WIDX_LAND_COST].top };
screenCoords = w->windowPos + ScreenCoordsXY{ landCostWidget.left + 1, landCostWidget.top };
auto ft = Formatter();
ft.Add<money64>(gLandPrice);
DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft);
}
if (w->widgets[WIDX_CONSTRUCTION_RIGHTS_COST].type != WindowWidgetType::Empty)
const auto& constructionRightsCostWidget = w->widgets[WIDX_CONSTRUCTION_RIGHTS_COST];
if (constructionRightsCostWidget.type != WindowWidgetType::Empty)
{
// Cost to buy construction rights label
screenCoords = w->windowPos + ScreenCoordsXY{ 8, w->widgets[WIDX_CONSTRUCTION_RIGHTS_COST].top };
screenCoords = w->windowPos + ScreenCoordsXY{ 8, constructionRightsCostWidget.top };
DrawTextBasic(dpi, screenCoords, STR_RIGHTS_COST_LABEL);
// Cost to buy construction rights value
screenCoords = w->windowPos
+ ScreenCoordsXY{ w->widgets[WIDX_CONSTRUCTION_RIGHTS_COST].left + 1,
w->widgets[WIDX_CONSTRUCTION_RIGHTS_COST].top };
screenCoords = w->windowPos + ScreenCoordsXY{ constructionRightsCostWidget.left + 1, constructionRightsCostWidget.top };
auto ft = Formatter();
ft.Add<money64>(gConstructionRightsPrice);
DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft);
}
if (w->widgets[WIDX_PAY_FOR_PARK_OR_RIDES].type != WindowWidgetType::Empty)
const auto& payForParkOrRidesWidget = w->widgets[WIDX_PAY_FOR_PARK_OR_RIDES];
if (payForParkOrRidesWidget.type != WindowWidgetType::Empty)
{
// Pay for park or rides label
screenCoords = w->windowPos
+ ScreenCoordsXY{ w->widgets[WIDX_PAY_FOR_PARK_OR_RIDES].left + 1, w->widgets[WIDX_PAY_FOR_PARK_OR_RIDES].top };
screenCoords = w->windowPos + ScreenCoordsXY{ payForParkOrRidesWidget.left + 1, payForParkOrRidesWidget.top };
auto ft = Formatter();
// Pay for park and/or rides value
@ -1377,26 +1376,27 @@ static void window_editor_scenario_options_park_paint(rct_window* w, rct_drawpix
DrawTextBasic(dpi, screenCoords, STR_WINDOW_COLOUR_2_STRINGID, ft);
}
if (w->widgets[WIDX_ENTRY_PRICE].type != WindowWidgetType::Empty)
const auto& entryPriceWidget = w->widgets[WIDX_ENTRY_PRICE];
if (entryPriceWidget.type != WindowWidgetType::Empty)
{
// Entry price label
screenCoords = w->windowPos
+ ScreenCoordsXY{ w->widgets[WIDX_PAY_FOR_PARK_OR_RIDES].right + 8, w->widgets[WIDX_ENTRY_PRICE].top };
screenCoords = w->windowPos + ScreenCoordsXY{ entryPriceWidget.right + 8, entryPriceWidget.top };
DrawTextBasic(dpi, screenCoords, STR_ENTRY_PRICE_LABEL);
// Entry price value
screenCoords = w->windowPos + ScreenCoordsXY{ w->widgets[WIDX_ENTRY_PRICE].left + 1, w->widgets[WIDX_ENTRY_PRICE].top };
screenCoords = w->windowPos + ScreenCoordsXY{ entryPriceWidget.left + 1, entryPriceWidget.top };
auto ft = Formatter();
ft.Add<money64>(gParkEntranceFee);
DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft);
}
// Climate label
screenCoords = w->windowPos + ScreenCoordsXY{ 8, w->widgets[WIDX_CLIMATE].top };
const auto& climateWidget = w->widgets[WIDX_CLIMATE];
screenCoords = w->windowPos + ScreenCoordsXY{ 8, climateWidget.top };
DrawTextBasic(dpi, screenCoords, STR_CLIMATE_LABEL);
// Climate value
screenCoords = w->windowPos + ScreenCoordsXY{ w->widgets[WIDX_CLIMATE].left + 1, w->widgets[WIDX_CLIMATE].top };
screenCoords = w->windowPos + ScreenCoordsXY{ climateWidget.left + 1, climateWidget.top };
auto ft = Formatter();
ft.Add<rct_string_id>(ClimateNames[static_cast<uint8_t>(gClimate)]);
DrawTextBasic(dpi, screenCoords, STR_WINDOW_COLOUR_2_STRINGID, ft);

View File

@ -745,10 +745,10 @@ void window_guest_viewport_init(rct_window* w)
if (peep->State != PeepState::Picked && w->viewport == nullptr)
{
auto view_widget = &w->widgets[WIDX_VIEWPORT];
auto screenPos = ScreenCoordsXY{ view_widget->left + 1 + w->windowPos.x, view_widget->top + 1 + w->windowPos.y };
int32_t width = view_widget->width() - 1;
int32_t height = view_widget->height() - 1;
const auto& view_widget = w->widgets[WIDX_VIEWPORT];
auto screenPos = ScreenCoordsXY{ view_widget.left + 1 + w->windowPos.x, view_widget.top + 1 + w->windowPos.y };
int32_t width = view_widget.width() - 1;
int32_t height = view_widget.height() - 1;
viewport_create(w, screenPos, width, height, w->focus.value());
if (w->viewport != nullptr && reCreateViewport)
@ -771,10 +771,10 @@ static void window_guest_overview_tab_paint(rct_window* w, rct_drawpixelinfo* dp
if (w->disabled_widgets & (1ULL << WIDX_TAB_1))
return;
rct_widget* widget = &w->widgets[WIDX_TAB_1];
int32_t width = widget->width() - 1;
int32_t height = widget->height() - 1;
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget->left + 1, widget->top + 1 };
const auto& widget = w->widgets[WIDX_TAB_1];
int32_t width = widget.width() - 1;
int32_t height = widget.height() - 1;
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget.left + 1, widget.top + 1 };
if (w->page == WINDOW_GUEST_OVERVIEW)
height++;
@ -843,8 +843,8 @@ static void window_guest_stats_tab_paint(rct_window* w, rct_drawpixelinfo* dpi)
if (w->disabled_widgets & (1ULL << WIDX_TAB_2))
return;
rct_widget* widget = &w->widgets[WIDX_TAB_2];
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
const auto& widget = w->widgets[WIDX_TAB_2];
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget.left, widget.top };
const auto peep = GetGuest(w);
if (peep == nullptr)
@ -881,8 +881,8 @@ static void window_guest_rides_tab_paint(rct_window* w, rct_drawpixelinfo* dpi)
if (w->disabled_widgets & (1ULL << WIDX_TAB_3))
return;
rct_widget* widget = &w->widgets[WIDX_TAB_3];
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
const auto& widget = w->widgets[WIDX_TAB_3];
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget.left, widget.top };
int32_t image_id = SPR_TAB_RIDE_0;
@ -903,8 +903,8 @@ static void window_guest_finance_tab_paint(rct_window* w, rct_drawpixelinfo* dpi
if (w->disabled_widgets & (1ULL << WIDX_TAB_4))
return;
rct_widget* widget = &w->widgets[WIDX_TAB_4];
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
const auto& widget = w->widgets[WIDX_TAB_4];
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget.left, widget.top };
int32_t image_id = SPR_TAB_FINANCES_SUMMARY_0;
@ -925,8 +925,8 @@ static void window_guest_thoughts_tab_paint(rct_window* w, rct_drawpixelinfo* dp
if (w->disabled_widgets & (1ULL << WIDX_TAB_5))
return;
rct_widget* widget = &w->widgets[WIDX_TAB_5];
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
const auto& widget = w->widgets[WIDX_TAB_5];
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget.left, widget.top };
int32_t image_id = SPR_TAB_THOUGHTS_0;
@ -947,8 +947,8 @@ static void window_guest_inventory_tab_paint(rct_window* w, rct_drawpixelinfo* d
if (w->disabled_widgets & (1ULL << WIDX_TAB_6))
return;
rct_widget* widget = &w->widgets[WIDX_TAB_6];
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
const auto& widget = w->widgets[WIDX_TAB_6];
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget.left, widget.top };
gfx_draw_sprite(dpi, ImageId(SPR_TAB_GUEST_INVENTORY), screenCoords);
}
@ -958,8 +958,8 @@ static void window_guest_debug_tab_paint(rct_window* w, rct_drawpixelinfo* dpi)
if (w->disabled_widgets & (1ULL << WIDX_TAB_7))
return;
rct_widget* widget = &w->widgets[WIDX_TAB_7];
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
const auto& widget = w->widgets[WIDX_TAB_7];
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget.left, widget.top };
int32_t image_id = SPR_TAB_GEARS_0;
if (w->page == WINDOW_GUEST_DEBUG)
@ -1003,22 +1003,22 @@ void window_guest_overview_paint(rct_window* w, rct_drawpixelinfo* dpi)
return;
}
rct_widget* widget = &w->widgets[WIDX_ACTION_LBL];
auto screenPos = w->windowPos + ScreenCoordsXY{ widget->midX(), widget->top - 1 };
const auto& actionLabelWidget = w->widgets[WIDX_ACTION_LBL];
auto screenPos = w->windowPos + ScreenCoordsXY{ actionLabelWidget.midX(), actionLabelWidget.top - 1 };
{
auto ft = Formatter();
peep->FormatActionTo(ft);
int32_t width = widget->width();
int32_t width = actionLabelWidget.width();
DrawTextEllipsised(dpi, screenPos, width, STR_BLACK_STRING, ft, { TextAlignment::CENTRE });
}
// Draw the marquee thought
widget = &w->widgets[WIDX_MARQUEE];
auto width = widget->width() - 3;
int32_t left = widget->left + 2 + w->windowPos.x;
int32_t top = widget->top + w->windowPos.y;
int32_t height = widget->height();
const auto& marqueeWidget = w->widgets[WIDX_MARQUEE];
auto width = marqueeWidget.width() - 3;
int32_t left = marqueeWidget.left + 2 + w->windowPos.x;
int32_t top = marqueeWidget.top + w->windowPos.y;
int32_t height = marqueeWidget.height();
rct_drawpixelinfo dpi_marquee;
if (!clip_drawpixelinfo(&dpi_marquee, dpi, { left, top }, width, height))
{
@ -1044,7 +1044,7 @@ void window_guest_overview_paint(rct_window* w, rct_drawpixelinfo* dpi)
return;
}
screenPos.x = widget->width() - w->list_information_type;
screenPos.x = marqueeWidget.width() - w->list_information_type;
{
auto ft = Formatter();
peep_thought_set_format_args(&peep->Thoughts[i], ft);

View File

@ -180,8 +180,8 @@ static void window_news_options_invalidate(rct_window* w)
w->pressed_widgets |= (1ULL << (WIDX_TAB_PARK + w->page));
// Set checkboxes
rct_widget* baseCheckBox = &w->widgets[WIDX_CHECKBOX_0];
int32_t y = baseCheckBox->top;
const auto& baseCheckBox = w->widgets[WIDX_CHECKBOX_0];
int32_t y = baseCheckBox.top;
int32_t checkboxWidgetIndex = WIDX_CHECKBOX_0;
rct_widget* checkboxWidget = &w->widgets[checkboxWidgetIndex];
@ -194,8 +194,8 @@ static void window_news_options_invalidate(rct_window* w)
w->enabled_widgets |= (1ULL << checkboxWidgetIndex);
checkboxWidget->type = WindowWidgetType::Checkbox;
checkboxWidget->left = baseCheckBox->left;
checkboxWidget->right = baseCheckBox->right;
checkboxWidget->left = baseCheckBox.left;
checkboxWidget->right = baseCheckBox.right;
checkboxWidget->top = y;
checkboxWidget->bottom = checkboxWidget->top + LIST_ROW_HEIGHT + 3;
checkboxWidget->text = ndef->caption;
@ -266,9 +266,8 @@ static void window_news_options_draw_tab_image(rct_window* w, rct_drawpixelinfo*
}
}
gfx_draw_sprite(
dpi, ImageId(spriteIndex),
w->windowPos + ScreenCoordsXY{ w->widgets[widgetIndex].left, w->widgets[widgetIndex].top });
const auto& widget = w->widgets[widgetIndex];
gfx_draw_sprite(dpi, ImageId(spriteIndex), w->windowPos + ScreenCoordsXY{ widget.left, widget.top });
}
}

View File

@ -1474,10 +1474,10 @@ static void window_options_audio_dropdown(rct_window* w, rct_widgetindex widgetI
}
}
static uint8_t get_scroll_percentage(rct_widget* widget, rct_scroll* scroll)
static uint8_t get_scroll_percentage(const rct_widget& widget, const rct_scroll& scroll)
{
uint8_t width = widget->width() - 1;
return static_cast<float>(scroll->h_left) / (scroll->h_right - width) * 100;
uint8_t width = widget.width() - 1;
return static_cast<float>(scroll.h_left) / (scroll.h_right - width) * 100;
}
static void window_options_audio_update(rct_window* w)
@ -1486,10 +1486,9 @@ static void window_options_audio_update(rct_window* w)
if (w->page == WINDOW_OPTIONS_PAGE_AUDIO)
{
rct_widget* widget;
widget = &window_options_audio_widgets[WIDX_MASTER_VOLUME];
uint8_t master_volume = get_scroll_percentage(widget, &w->scrolls[0]);
const auto& masterVolumeWidget = window_options_audio_widgets[WIDX_MASTER_VOLUME];
const auto& masterVolumeScroll = w->scrolls[0];
uint8_t master_volume = get_scroll_percentage(masterVolumeWidget, masterVolumeScroll);
if (master_volume != gConfigSound.master_volume)
{
gConfigSound.master_volume = master_volume;
@ -1497,8 +1496,9 @@ static void window_options_audio_update(rct_window* w)
widget_invalidate(w, WIDX_MASTER_VOLUME);
}
widget = &window_options_audio_widgets[WIDX_SOUND_VOLUME];
uint8_t sound_volume = get_scroll_percentage(widget, &w->scrolls[1]);
const auto& soundVolumeWidget = window_options_audio_widgets[WIDX_MASTER_VOLUME];
const auto& soundVolumeScroll = w->scrolls[1];
uint8_t sound_volume = get_scroll_percentage(soundVolumeWidget, soundVolumeScroll);
if (sound_volume != gConfigSound.sound_volume)
{
gConfigSound.sound_volume = sound_volume;
@ -1506,8 +1506,9 @@ static void window_options_audio_update(rct_window* w)
widget_invalidate(w, WIDX_SOUND_VOLUME);
}
widget = &window_options_audio_widgets[WIDX_MUSIC_VOLUME];
uint8_t ride_music_volume = get_scroll_percentage(widget, &w->scrolls[2]);
const auto& musicVolumeWidget = window_options_audio_widgets[WIDX_MASTER_VOLUME];
const auto& musicVolumeScroll = w->scrolls[2];
uint8_t ride_music_volume = get_scroll_percentage(musicVolumeWidget, musicVolumeScroll);
if (ride_music_volume != gConfigSound.ride_music_volume)
{
gConfigSound.ride_music_volume = ride_music_volume;
@ -1524,11 +1525,11 @@ static void window_options_audio_scrollgetsize(rct_window* w, int32_t scrollInde
static void initialize_scroll_position(rct_window* w, rct_widgetindex widget_index, int32_t scroll_id, uint8_t volume)
{
rct_widget* widget = &window_options_audio_widgets[widget_index];
rct_scroll* scroll = &w->scrolls[scroll_id];
const auto& widget = window_options_audio_widgets[widget_index];
auto& scroll = w->scrolls[scroll_id];
int widget_size = scroll->h_right - (widget->width() - 1);
scroll->h_left = ceil(volume / 100.0f * widget_size);
int32_t widget_size = scroll.h_right - (widget.width() - 1);
scroll.h_left = ceil(volume / 100.0f * widget_size);
WidgetScrollUpdateThumbs(w, widget_index);
}

View File

@ -944,9 +944,8 @@ static void window_ride_draw_tab_image(rct_drawpixelinfo* dpi, rct_window* w, in
spriteIndex += (frame % window_ride_tab_animation_frames[w->page]);
}
gfx_draw_sprite(
dpi, ImageId(spriteIndex),
w->windowPos + ScreenCoordsXY{ w->widgets[widgetIndex].left, w->widgets[widgetIndex].top });
const auto& widget = w->widgets[widgetIndex];
gfx_draw_sprite(dpi, ImageId(spriteIndex), w->windowPos + ScreenCoordsXY{ widget.left, widget.top });
}
}
@ -981,9 +980,9 @@ static void window_ride_draw_tab_main(rct_drawpixelinfo* dpi, rct_window* w)
spriteIndex += (w->frame_no / 4) % 8;
break;
}
gfx_draw_sprite(
dpi, ImageId(spriteIndex),
w->windowPos + ScreenCoordsXY{ w->widgets[widgetIndex].left, w->widgets[widgetIndex].top });
const auto& widget = w->widgets[widgetIndex];
gfx_draw_sprite(dpi, ImageId(spriteIndex), w->windowPos + ScreenCoordsXY{ widget.left, widget.top });
}
}
}
@ -995,13 +994,13 @@ static void window_ride_draw_tab_main(rct_drawpixelinfo* dpi, rct_window* w)
static void window_ride_draw_tab_vehicle(rct_drawpixelinfo* dpi, rct_window* w)
{
rct_widgetindex widgetIndex = WIDX_TAB_1 + WINDOW_RIDE_PAGE_VEHICLE;
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
if (!(w->disabled_widgets & (1LL << widgetIndex)))
{
auto screenCoords = ScreenCoordsXY{ widget->left + 1, widget->top + 1 };
int32_t width = widget->right - screenCoords.x;
int32_t height = widget->bottom - 3 - screenCoords.y;
auto screenCoords = ScreenCoordsXY{ widget.left + 1, widget.top + 1 };
int32_t width = widget.right - screenCoords.x;
int32_t height = widget.bottom - 3 - screenCoords.y;
if (w->page == WINDOW_RIDE_PAGE_VEHICLE)
height += 4;
@ -1013,7 +1012,7 @@ static void window_ride_draw_tab_vehicle(rct_drawpixelinfo* dpi, rct_window* w)
return;
}
screenCoords = ScreenCoordsXY{ widget->width() / 2, widget->height() - 12 };
screenCoords = ScreenCoordsXY{ widget.width() / 2, widget.height() - 12 };
auto ride = get_ride(w->rideId);
if (ride == nullptr)
@ -1070,7 +1069,7 @@ static void window_ride_draw_tab_customer(rct_drawpixelinfo* dpi, rct_window* w)
if (!(w->disabled_widgets & (1LL << widgetIndex)))
{
rct_widget* widget = &w->widgets[widgetIndex];
const auto& widget = w->widgets[widgetIndex];
int32_t spriteIndex = 0;
if (w->page == WINDOW_RIDE_PAGE_CUSTOMER)
spriteIndex = w->picked_peep_frame & ~3;
@ -1080,7 +1079,7 @@ static void window_ride_draw_tab_customer(rct_drawpixelinfo* dpi, rct_window* w)
spriteIndex |= 0xA9E00000;
gfx_draw_sprite(
dpi, ImageId::FromUInt32(spriteIndex), w->windowPos + ScreenCoordsXY{ widget->midX(), widget->bottom - 6 });
dpi, ImageId::FromUInt32(spriteIndex), w->windowPos + ScreenCoordsXY{ widget.midX(), widget.bottom - 6 });
}
}
@ -1656,11 +1655,11 @@ static void window_ride_init_viewport(rct_window* w)
// rct2: 0x006aec9c only used here so brought it into the function
if (w->viewport == nullptr && !ride->overall_view.IsNull())
{
rct_widget* view_widget = &w->widgets[WIDX_VIEWPORT];
const auto& view_widget = w->widgets[WIDX_VIEWPORT];
auto screenPos = w->windowPos + ScreenCoordsXY{ view_widget->left + 1, view_widget->top + 1 };
int32_t width = view_widget->width() - 1;
int32_t height = view_widget->height() - 1;
auto screenPos = w->windowPos + ScreenCoordsXY{ view_widget.left + 1, view_widget.top + 1 };
int32_t width = view_widget.width() - 1;
int32_t height = view_widget.height() - 1;
viewport_create(w, screenPos, width, height, w->focus.value());
@ -4807,7 +4806,6 @@ static void window_ride_colour_paint(rct_window* w, rct_drawpixelinfo* dpi)
{
// TODO: This should use lists and identified sprites
rct_drawpixelinfo clippedDpi;
rct_widget* widget;
auto ride = get_ride(w->rideId);
if (ride == nullptr)
@ -4817,12 +4815,12 @@ static void window_ride_colour_paint(rct_window* w, rct_drawpixelinfo* dpi)
window_ride_draw_tab_images(dpi, w);
// Track / shop item preview
widget = &window_ride_colour_widgets[WIDX_TRACK_PREVIEW];
if (widget->type != WindowWidgetType::Empty)
const auto& trackPreviewWidget = window_ride_colour_widgets[WIDX_TRACK_PREVIEW];
if (trackPreviewWidget.type != WindowWidgetType::Empty)
gfx_fill_rect(
dpi,
{ { w->windowPos + ScreenCoordsXY{ widget->left + 1, widget->top + 1 } },
{ w->windowPos + ScreenCoordsXY{ widget->right - 1, widget->bottom - 1 } } },
{ { w->windowPos + ScreenCoordsXY{ trackPreviewWidget.left + 1, trackPreviewWidget.top + 1 } },
{ w->windowPos + ScreenCoordsXY{ trackPreviewWidget.right - 1, trackPreviewWidget.bottom - 1 } } },
PALETTE_INDEX_12);
auto trackColour = ride_get_track_colour(ride, w->ride_colour);
@ -4831,7 +4829,7 @@ static void window_ride_colour_paint(rct_window* w, rct_drawpixelinfo* dpi)
auto rideEntry = ride->GetRideEntry();
if (rideEntry == nullptr || rideEntry->shop_item[0] == ShopItem::None)
{
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
auto screenCoords = w->windowPos + ScreenCoordsXY{ trackPreviewWidget.left, trackPreviewWidget.top };
// Track
if (ride->type == RIDE_TYPE_MAZE)
@ -4858,7 +4856,8 @@ static void window_ride_colour_paint(rct_window* w, rct_drawpixelinfo* dpi)
else
{
auto screenCoords = w->windowPos
+ ScreenCoordsXY{ (widget->left + widget->right) / 2 - 8, (widget->bottom + widget->top) / 2 - 6 };
+ ScreenCoordsXY{ (trackPreviewWidget.left + trackPreviewWidget.right) / 2 - 8,
(trackPreviewWidget.bottom + trackPreviewWidget.top) / 2 - 6 };
ShopItem shopItem = rideEntry->shop_item[1] == ShopItem::None ? rideEntry->shop_item[0] : rideEntry->shop_item[1];
gfx_draw_sprite(dpi, ImageId(GetShopItemDescriptor(shopItem).Image, ride->track_colour[0].main), screenCoords);
@ -4866,12 +4865,13 @@ static void window_ride_colour_paint(rct_window* w, rct_drawpixelinfo* dpi)
// Entrance preview
trackColour = ride_get_track_colour(ride, 0);
widget = &w->widgets[WIDX_ENTRANCE_PREVIEW];
if (widget->type != WindowWidgetType::Empty)
const auto& entrancePreviewWidget = w->widgets[WIDX_ENTRANCE_PREVIEW];
if (entrancePreviewWidget.type != WindowWidgetType::Empty)
{
if (clip_drawpixelinfo(
&clippedDpi, dpi, w->windowPos + ScreenCoordsXY{ widget->left + 1, widget->top + 1 }, widget->width(),
widget->height()))
&clippedDpi, dpi,
w->windowPos + ScreenCoordsXY{ entrancePreviewWidget.left + 1, entrancePreviewWidget.top + 1 },
entrancePreviewWidget.width(), entrancePreviewWidget.height()))
{
gfx_clear(&clippedDpi, PALETTE_INDEX_12);

View File

@ -245,16 +245,16 @@ static void window_scenarioselect_init_tabs(rct_window* w)
int32_t x = 3;
for (int32_t i = 0; i < NumTabs; i++)
{
rct_widget* widget = &w->widgets[i + WIDX_TAB1];
auto& widget = w->widgets[i + WIDX_TAB1];
if (!(showPages & (1 << i)))
{
widget->type = WindowWidgetType::Empty;
widget.type = WindowWidgetType::Empty;
continue;
}
widget->type = WindowWidgetType::Tab;
widget->left = x;
widget->right = x + 90;
widget.type = WindowWidgetType::Tab;
widget.left = x;
widget.right = x + 90;
x += 91;
}
}
@ -563,8 +563,8 @@ static void window_scenarioselect_scrollpaint(rct_window* w, rct_drawpixelinfo*
rct_string_id highlighted_format = ScenarioSelectUseSmallFont() ? STR_WHITE_STRING : STR_WINDOW_COLOUR_2_STRINGID;
rct_string_id unhighlighted_format = ScenarioSelectUseSmallFont() ? STR_WHITE_STRING : STR_BLACK_STRING;
rct_widget* listWidget = &w->widgets[WIDX_SCENARIOLIST];
int32_t listWidth = listWidget->width() - 12;
const auto& listWidget = w->widgets[WIDX_SCENARIOLIST];
int32_t listWidth = listWidget.width() - 12;
const int32_t scenarioItemHeight = get_scenario_list_item_size();

View File

@ -978,7 +978,7 @@ void window_scenery_invalidate(rct_window* w)
}
auto* sceneryEntry = get_small_scenery_entry(tabSelectedScenery.EntryIndex);
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_ROTATABLE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_ROTATABLE))
{
w->widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].type = WindowWidgetType::FlatBtn;
}
@ -1048,12 +1048,11 @@ void window_scenery_invalidate(rct_window* w)
{
auto* sceneryEntry = get_small_scenery_entry(tabSelectedScenery.EntryIndex);
if (scenery_small_entry_has_flag(
sceneryEntry, SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR | SMALL_SCENERY_FLAG_HAS_GLASS))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR | SMALL_SCENERY_FLAG_HAS_GLASS))
{
w->widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].type = WindowWidgetType::ColourBtn;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR))
w->widgets[WIDX_SCENERY_SECONDARY_COLOUR_BUTTON].type = WindowWidgetType::ColourBtn;
}
}
@ -1286,11 +1285,11 @@ static void window_scenery_scrollpaint_item(rct_window* w, rct_drawpixelinfo* dp
auto sceneryEntry = get_small_scenery_entry(scenerySelection.EntryIndex);
uint32_t imageId = sceneryEntry->image + gWindowSceneryRotation;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR))
{
imageId |= (gWindowSceneryPrimaryColour << 19) | IMAGE_TYPE_REMAP;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR))
{
imageId |= (gWindowScenerySecondaryColour << 24) | IMAGE_TYPE_REMAP_2_PLUS;
}
@ -1298,15 +1297,14 @@ static void window_scenery_scrollpaint_item(rct_window* w, rct_drawpixelinfo* dp
uint16_t spriteTop = (sceneryEntry->height / 4) + 0x2B;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE)
&& scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE) && sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
{
spriteTop -= 0x0C;
}
gfx_draw_sprite(dpi, imageId, { 0x20, spriteTop }, w->colours[1]);
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_HAS_GLASS))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_HAS_GLASS))
{
imageId = ((sceneryEntry->image + gWindowSceneryRotation) + 0x40000004)
+ (EnumValue(GlassPaletteIds[gWindowSceneryPrimaryColour]) << 19);
@ -1314,7 +1312,7 @@ static void window_scenery_scrollpaint_item(rct_window* w, rct_drawpixelinfo* dp
gfx_draw_sprite(dpi, imageId, { 0x20, spriteTop }, w->colours[1]);
}
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_ANIMATED_FG))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_ANIMATED_FG))
{
imageId = (sceneryEntry->image + gWindowSceneryRotation) + 4;
gfx_draw_sprite(dpi, imageId, { 0x20, spriteTop }, w->colours[1]);

View File

@ -260,7 +260,7 @@ static void window_server_list_scroll_mousedown(rct_window* w, int32_t scrollInd
{
const auto& server = _serverList.GetServer(serverIndex);
auto listWidget = &w->widgets[WIDX_LIST];
const auto& listWidget = w->widgets[WIDX_LIST];
gDropdownItemsFormat[0] = STR_JOIN_GAME;
if (server.Favourite)
@ -271,8 +271,8 @@ static void window_server_list_scroll_mousedown(rct_window* w, int32_t scrollInd
{
gDropdownItemsFormat[1] = STR_ADD_TO_FAVOURITES;
}
auto dropdownPos = ScreenCoordsXY{ w->windowPos.x + listWidget->left + screenCoords.x + 2 - w->scrolls[0].h_left,
w->windowPos.y + listWidget->top + screenCoords.y + 2 - w->scrolls[0].v_top };
auto dropdownPos = ScreenCoordsXY{ w->windowPos.x + listWidget.left + screenCoords.x + 2 - w->scrolls[0].h_left,
w->windowPos.y + listWidget.top + screenCoords.y + 2 - w->scrolls[0].v_top };
WindowDropdownShowText(dropdownPos, 0, COLOUR_GREY, 0, 2);
}
}
@ -287,9 +287,10 @@ static void window_server_list_scroll_mouseover(rct_window* w, int32_t scrollInd
}
int32_t hoverButtonIndex = -1;
auto& listWidget = w->widgets[WIDX_LIST];
if (index != -1)
{
int32_t width = w->widgets[WIDX_LIST].width();
int32_t width = listWidget.width();
int32_t sy = index * ITEM_HEIGHT;
for (int32_t i = 0; i < 2; i++)
{
@ -304,11 +305,11 @@ static void window_server_list_scroll_mouseover(rct_window* w, int32_t scrollInd
}
}
int32_t width = w->widgets[WIDX_LIST].width();
int32_t width = listWidget.width();
int32_t right = width - 3 - 14 - 10;
if (screenCoords.x < right)
{
w->widgets[WIDX_LIST].tooltip = STR_NONE;
listWidget.tooltip = STR_NONE;
window_tooltip_close();
}
@ -421,11 +422,12 @@ static void window_server_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi
uint8_t paletteIndex = ColourMapA[w->colours[1]].mid_light;
gfx_clear(dpi, paletteIndex);
int32_t width = w->widgets[WIDX_LIST].width();
auto& listWidget = w->widgets[WIDX_LIST];
int32_t width = listWidget.width();
ScreenCoordsXY screenCoords;
screenCoords.y = 0;
w->widgets[WIDX_LIST].tooltip = STR_NONE;
listWidget.tooltip = STR_NONE;
for (int32_t i = 0; i < w->no_list_items; i++)
{
if (screenCoords.y >= dpi->y + dpi->height)
@ -439,7 +441,7 @@ static void window_server_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi
{
gfx_filter_rect(dpi, 0, screenCoords.y, width, screenCoords.y + ITEM_HEIGHT, FilterPaletteID::PaletteDarken1);
_version = serverDetails.Version;
w->widgets[WIDX_LIST].tooltip = STR_NETWORK_VERSION_TIP;
listWidget.tooltip = STR_NETWORK_VERSION_TIP;
}
colour_t colour = w->colours[1];

View File

@ -967,9 +967,9 @@ void window_staff_overview_paint(rct_window* w, rct_drawpixelinfo* dpi)
}
auto ft = Formatter();
peep->FormatActionTo(ft);
rct_widget* widget = &w->widgets[WIDX_BTM_LABEL];
auto screenPos = w->windowPos + ScreenCoordsXY{ widget->midX(), widget->top };
int32_t width = widget->width();
const auto& widget = w->widgets[WIDX_BTM_LABEL];
auto screenPos = w->windowPos + ScreenCoordsXY{ widget.midX(), widget.top };
int32_t width = widget.width();
DrawTextEllipsised(dpi, screenPos, width, STR_BLACK_STRING, ft, { TextAlignment::CENTRE });
}
@ -982,16 +982,14 @@ void window_staff_options_tab_paint(rct_window* w, rct_drawpixelinfo* dpi)
if (w->disabled_widgets & (1ULL << WIDX_TAB_2))
return;
rct_widget* widget = &w->widgets[WIDX_TAB_2];
int32_t image_id = SPR_TAB_STAFF_OPTIONS_0;
if (w->page == WINDOW_STAFF_OPTIONS)
{
image_id += (w->frame_no / 2) % 7;
}
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
const auto& widget = w->widgets[WIDX_TAB_2];
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget.left, widget.top };
gfx_draw_sprite(dpi, ImageId(image_id), screenCoords);
}
@ -1004,16 +1002,14 @@ void window_staff_stats_tab_paint(rct_window* w, rct_drawpixelinfo* dpi)
if (w->disabled_widgets & (1ULL << WIDX_TAB_3))
return;
rct_widget* widget = &w->widgets[WIDX_TAB_3];
int32_t image_id = SPR_TAB_STATS_0;
if (w->page == WINDOW_STAFF_STATISTICS)
{
image_id += (w->frame_no / 4) % 7;
}
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
const auto& widget = w->widgets[WIDX_TAB_3];
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget.left, widget.top };
gfx_draw_sprite(dpi, ImageId(image_id), screenCoords);
}
@ -1025,10 +1021,10 @@ void window_staff_overview_tab_paint(rct_window* w, rct_drawpixelinfo* dpi)
if (w->disabled_widgets & (1ULL << WIDX_TAB_1))
return;
rct_widget* widget = &w->widgets[WIDX_TAB_1];
int32_t width = widget->width() - 1;
int32_t height = widget->height() - 1;
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget->left + 1, widget->top + 1 };
const auto& widget = w->widgets[WIDX_TAB_1];
int32_t width = widget.width() - 1;
int32_t height = widget.height() - 1;
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget.left + 1, widget.top + 1 };
if (w->page == WINDOW_STAFF_OVERVIEW)
height++;
@ -1379,11 +1375,11 @@ void window_staff_viewport_init(rct_window* w)
{
if (w->viewport == nullptr)
{
rct_widget* view_widget = &w->widgets[WIDX_VIEWPORT];
const auto& view_widget = w->widgets[WIDX_VIEWPORT];
auto screenPos = ScreenCoordsXY{ view_widget->left + 1 + w->windowPos.x, view_widget->top + 1 + w->windowPos.y };
int32_t width = view_widget->width() - 1;
int32_t height = view_widget->height() - 1;
auto screenPos = ScreenCoordsXY{ view_widget.left + 1 + w->windowPos.x, view_widget.top + 1 + w->windowPos.y };
int32_t width = view_widget.width() - 1;
int32_t height = view_widget.height() - 1;
viewport_create(w, screenPos, width, height, focus.value());
w->flags |= WF_NO_SCROLLING;

View File

@ -1994,7 +1994,7 @@ static void window_tile_inspector_paint(rct_window* w, rct_drawpixelinfo* dpi)
// Quadrant value
const auto* sceneryEntry = tileElement->AsSmallScenery()->GetEntry();
if (sceneryEntry != nullptr && !(scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE)))
if (sceneryEntry != nullptr && !(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE)))
{
int16_t quadrant = tileElement->AsSmallScenery()->GetSceneryQuadrant();
static rct_string_id quadrant_string_idx[] = { STR_TILE_INSPECTOR_SCENERY_QUADRANT_SW,

View File

@ -122,11 +122,10 @@ enum FILE_MENU_DDIDX {
DDIDX_GIANT_SCREENSHOT = 8,
// separator
DDIDX_FILE_BUG_ON_GITHUB = 10,
DDIDX_UPDATE_AVAILABLE = 11,
// separator
DDIDX_QUIT_TO_MENU = 12,
DDIDX_EXIT_OPENRCT2 = 13,
// separator
DDIDX_UPDATE_AVAILABLE = 15,
DDIDX_QUIT_TO_MENU = 13,
DDIDX_EXIT_OPENRCT2 = 14,
};
enum TOP_TOOLBAR_VIEW_MENU_DDIDX {
@ -440,12 +439,18 @@ static void window_top_toolbar_mousedown(rct_window* w, rct_widgetindex widgetIn
gDropdownItemsFormat[numItems++] = STR_GIANT_SCREENSHOT;
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_FILE_BUG_ON_GITHUB;
if (OpenRCT2::GetContext()->HasNewVersionInfo())
gDropdownItemsFormat[numItems++] = STR_UPDATE_AVAILABLE;
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_QUIT_TRACK_DESIGNS_MANAGER;
gDropdownItemsFormat[numItems++] = STR_EXIT_OPENRCT2;
if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER)
gDropdownItemsFormat[numItems++] = STR_QUIT_ROLLERCOASTER_DESIGNER;
else
gDropdownItemsFormat[numItems++] = STR_QUIT_TRACK_DESIGNS_MANAGER;
gDropdownItemsFormat[numItems++] = STR_EXIT_OPENRCT2;
}
else if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR)
{
@ -458,6 +463,10 @@ static void window_top_toolbar_mousedown(rct_window* w, rct_widgetindex widgetIn
gDropdownItemsFormat[numItems++] = STR_GIANT_SCREENSHOT;
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_FILE_BUG_ON_GITHUB;
if (OpenRCT2::GetContext()->HasNewVersionInfo())
gDropdownItemsFormat[numItems++] = STR_UPDATE_AVAILABLE;
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_QUIT_SCENARIO_EDITOR;
gDropdownItemsFormat[numItems++] = STR_EXIT_OPENRCT2;
@ -475,15 +484,15 @@ static void window_top_toolbar_mousedown(rct_window* w, rct_widgetindex widgetIn
gDropdownItemsFormat[numItems++] = STR_GIANT_SCREENSHOT;
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_FILE_BUG_ON_GITHUB;
if (OpenRCT2::GetContext()->HasNewVersionInfo())
gDropdownItemsFormat[numItems++] = STR_UPDATE_AVAILABLE;
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_QUIT_TO_MENU;
gDropdownItemsFormat[numItems++] = STR_EXIT_OPENRCT2;
if (OpenRCT2::GetContext()->HasNewVersionInfo())
{
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_UPDATE_AVAILABLE;
}
}
WindowDropdownShowText(
{ w->windowPos.x + widget->left, w->windowPos.y + widget->top }, widget->height() + 1, w->colours[0] | 0x80,
Dropdown::Flag::StayOpen, numItems);
@ -542,6 +551,10 @@ static void window_top_toolbar_dropdown(rct_window* w, rct_widgetindex widgetInd
if (gScreenFlags & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))
dropdownIndex += DDIDX_ABOUT;
// The "Update available" menu item is only available when there is one
if (dropdownIndex >= DDIDX_UPDATE_AVAILABLE && !OpenRCT2::GetContext()->HasNewVersionInfo())
dropdownIndex += 1;
switch (dropdownIndex)
{
case DDIDX_NEW_GAME:
@ -596,6 +609,9 @@ static void window_top_toolbar_dropdown(rct_window* w, rct_widgetindex widgetInd
OpenRCT2::GetContext()->GetUiContext()->OpenURL(url);
}
break;
case DDIDX_UPDATE_AVAILABLE:
context_open_window_view(WV_NEW_VERSION_INFO);
break;
case DDIDX_QUIT_TO_MENU:
{
window_close_by_class(WC_MANAGE_TRACK_DESIGN);
@ -607,9 +623,6 @@ static void window_top_toolbar_dropdown(rct_window* w, rct_widgetindex widgetInd
case DDIDX_EXIT_OPENRCT2:
context_quit();
break;
case DDIDX_UPDATE_AVAILABLE:
context_open_window_view(WV_NEW_VERSION_INFO);
break;
}
break;
case WIDX_CHEATS:
@ -1006,8 +1019,7 @@ static void repaint_scenery_tool_down(const ScreenCoordsXY& windowPos, rct_widge
auto* sceneryEntry = info.Element->AsSmallScenery()->GetEntry();
// If can't repaint
if (!scenery_small_entry_has_flag(
sceneryEntry, SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR | SMALL_SCENERY_FLAG_HAS_GLASS))
if (!sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR | SMALL_SCENERY_FLAG_HAS_GLASS))
return;
uint8_t quadrant = info.Element->AsSmallScenery()->GetSceneryQuadrant();
@ -1251,7 +1263,7 @@ static void sub_6E1F34_small_scenery(
auto* sceneryEntry = get_small_scenery_entry(sceneryIndex);
maxPossibleHeight -= sceneryEntry->height;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_STACKABLE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_STACKABLE))
{
can_raise_item = true;
}
@ -1259,7 +1271,7 @@ static void sub_6E1F34_small_scenery(
sub_6E1F34_update_screen_coords_and_buttons_pressed(can_raise_item, screenPos);
// Small scenery
if (!scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE))
if (!sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE))
{
uint8_t quadrant = 0;
@ -1323,7 +1335,7 @@ static void sub_6E1F34_small_scenery(
uint8_t rotation = gWindowSceneryRotation;
if (!scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_ROTATABLE))
if (!sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_ROTATABLE))
{
rotation = util_rand() & 0xFF;
}
@ -1407,7 +1419,7 @@ static void sub_6E1F34_small_scenery(
gridPos = gridPos.ToTileStart();
uint8_t rotation = gWindowSceneryRotation;
if (!scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_ROTATABLE))
if (!sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_ROTATABLE))
{
rotation = util_rand() & 0xFF;
}
@ -1764,7 +1776,7 @@ static void window_top_toolbar_scenery_tool_down(const ScreenCoordsXY& windowPos
if (isCluster)
{
if (!scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE))
if (!sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE))
{
quadrant = util_rand() & 3;
}
@ -1779,7 +1791,7 @@ static void window_top_toolbar_scenery_tool_down(const ScreenCoordsXY& windowPos
cur_grid_x += grid_x_offset * COORDS_XY_STEP;
cur_grid_y += grid_y_offset * COORDS_XY_STEP;
if (!scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_ROTATABLE))
if (!sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_ROTATABLE))
{
gSceneryPlaceRotation = (gSceneryPlaceRotation + 1) & 3;
}
@ -2462,18 +2474,18 @@ static money64 try_place_ghost_small_scenery(
auto smallSceneryPlaceAction = SmallSceneryPlaceAction(loc, quadrant, entryIndex, primaryColour, secondaryColour);
smallSceneryPlaceAction.SetFlags(GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED);
auto res = GameActions::Execute(&smallSceneryPlaceAction);
auto sspar = dynamic_cast<SmallSceneryPlaceActionResult*>(res.get());
if (sspar == nullptr || res->Error != GameActions::Status::Ok)
if (res->Error != GameActions::Status::Ok)
return MONEY64_UNDEFINED;
const auto placementData = res->GetData<SmallSceneryPlaceActionResult>();
gSceneryPlaceRotation = loc.direction;
gSceneryPlaceObject.SceneryType = SCENERY_TYPE_SMALL;
gSceneryPlaceObject.EntryIndex = entryIndex;
TileElement* tileElement = sspar->tileElement;
gSceneryGhostPosition = { loc, tileElement->GetBaseZ() };
gSceneryQuadrant = tileElement->AsSmallScenery()->GetSceneryQuadrant();
if (sspar->GroundFlags & ELEMENT_IS_UNDERGROUND)
gSceneryGhostPosition = { loc, placementData.BaseHeight };
gSceneryQuadrant = placementData.SceneryQuadrant;
if (placementData.GroundFlags & ELEMENT_IS_UNDERGROUND)
{
// Set underground on
viewport_set_visibility(4);
@ -2519,11 +2531,12 @@ static money64 try_place_ghost_wall(
// 6e26b0
auto wallPlaceAction = WallPlaceAction(entryIndex, loc, edge, primaryColour, secondaryColour, tertiaryColour);
wallPlaceAction.SetFlags(GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND);
wallPlaceAction.SetCallback([=](const GameAction* ga, const WallPlaceActionResult* result) {
wallPlaceAction.SetCallback([=](const GameAction* ga, const GameActions::Result* result) {
if (result->Error != GameActions::Status::Ok)
return;
gSceneryGhostPosition = { loc, result->tileElement->GetBaseZ() };
const auto placementData = result->GetData<WallPlaceActionResult>();
gSceneryGhostPosition = { loc, placementData.BaseHeight };
gSceneryGhostWallRotation = edge;
gSceneryGhostType |= SCENERY_GHOST_FLAG_2;
@ -2545,14 +2558,15 @@ static money64 try_place_ghost_large_scenery(
auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, entryIndex, primaryColour, secondaryColour);
sceneryPlaceAction.SetFlags(GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND);
auto res = GameActions::Execute(&sceneryPlaceAction);
auto lspar = dynamic_cast<LargeSceneryPlaceActionResult*>(res.get());
if (lspar == nullptr || res->Error != GameActions::Status::Ok)
if (res->Error != GameActions::Status::Ok)
return MONEY64_UNDEFINED;
const auto placementData = res->GetData<LargeSceneryPlaceActionResult>();
gSceneryPlaceRotation = loc.direction;
gSceneryGhostPosition = { loc, lspar->firstTileHeight };
if (lspar->GroundFlags & ELEMENT_IS_UNDERGROUND)
gSceneryGhostPosition = { loc, placementData.firstTileHeight };
if (placementData.GroundFlags & ELEMENT_IS_UNDERGROUND)
{
// Set underground on
viewport_set_visibility(4);
@ -2664,7 +2678,7 @@ static void top_toolbar_tool_update_scenery(const ScreenCoordsXY& screenPos)
auto* sceneryEntry = get_small_scenery_entry(selection.EntryIndex);
gMapSelectType = MAP_SELECT_TYPE_FULL;
if (!scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE) && !gWindowSceneryScatterEnabled)
if (!sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE) && !gWindowSceneryScatterEnabled)
{
gMapSelectType = MAP_SELECT_TYPE_QUARTER_0 + (quadrant ^ 2);
}
@ -3066,8 +3080,8 @@ static void window_top_toolbar_land_tool_drag(const ScreenCoordsXY& screenPos)
rct_widgetindex widget_index = window_find_widget_from_point(window, screenPos);
if (widget_index == -1)
return;
rct_widget* widget = &window->widgets[widget_index];
if (widget->type != WindowWidgetType::Viewport)
const auto& widget = window->widgets[widget_index];
if (widget.type != WindowWidgetType::Viewport)
return;
rct_viewport* viewport = window->viewport;
if (viewport == nullptr)
@ -3109,8 +3123,8 @@ static void window_top_toolbar_water_tool_drag(const ScreenCoordsXY& screenPos)
rct_widgetindex widget_index = window_find_widget_from_point(window, screenPos);
if (widget_index == -1)
return;
rct_widget* widget = &window->widgets[widget_index];
if (widget->type != WindowWidgetType::Viewport)
const auto& widget = window->widgets[widget_index];
if (widget.type != WindowWidgetType::Viewport)
return;
rct_viewport* viewport = window->viewport;
if (viewport == nullptr)

View File

@ -67,11 +67,11 @@ void ride_construct_new(RideSelection listItem)
auto gameAction = RideCreateAction(listItem.Type, listItem.EntryIndex, colour1, colour2);
gameAction.SetCallback([](const GameAction* ga, const RideCreateGameActionResult* result) {
gameAction.SetCallback([](const GameAction* ga, const GameActions::Result* result) {
if (result->Error != GameActions::Status::Ok)
return;
auto ride = get_ride(result->rideIndex);
const auto rideIndex = result->GetData<ride_id_t>();
auto ride = get_ride(rideIndex);
ride_construct(ride);
});

View File

@ -222,7 +222,7 @@ TileElement* LandSetHeightAction::CheckTreeObstructions() const
continue;
auto* sceneryEntry = sceneryElement->GetEntry();
if (!scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_IS_TREE))
if (!sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_IS_TREE))
continue;
return sceneryElement->as<TileElement>();

View File

@ -17,26 +17,6 @@
#include "../world/MapAnimation.h"
#include "../world/Surface.h"
LargeSceneryPlaceActionResult::LargeSceneryPlaceActionResult()
: GameActions::Result(GameActions::Status::Ok, STR_CANT_POSITION_THIS_HERE)
{
}
LargeSceneryPlaceActionResult::LargeSceneryPlaceActionResult(GameActions::Status error)
: GameActions::Result(error, STR_CANT_POSITION_THIS_HERE)
{
}
LargeSceneryPlaceActionResult::LargeSceneryPlaceActionResult(GameActions::Status error, rct_string_id message)
: GameActions::Result(error, STR_CANT_POSITION_THIS_HERE, message)
{
}
LargeSceneryPlaceActionResult::LargeSceneryPlaceActionResult(GameActions::Status error, rct_string_id message, uint8_t* args)
: GameActions::Result(error, STR_CANT_POSITION_THIS_HERE, message, args)
{
}
LargeSceneryPlaceAction::LargeSceneryPlaceAction(
const CoordsXYZD& loc, ObjectEntryIndex sceneryType, uint8_t primaryColour, uint8_t secondaryColour)
: _loc(loc)
@ -68,14 +48,15 @@ void LargeSceneryPlaceAction::Serialise(DataSerialiser& stream)
GameActions::Result::Ptr LargeSceneryPlaceAction::Query() const
{
auto res = std::make_unique<LargeSceneryPlaceActionResult>();
auto res = MakeResult();
res->ErrorTitle = STR_CANT_POSITION_THIS_HERE;
res->Expenditure = ExpenditureType::Landscaping;
int16_t surfaceHeight = tile_element_height(_loc);
res->Position.x = _loc.x + 16;
res->Position.y = _loc.y + 16;
res->Position.z = surfaceHeight;
res->GroundFlags = 0;
auto resultData = LargeSceneryPlaceActionResult{};
money32 supportsCost = 0;
@ -84,20 +65,20 @@ GameActions::Result::Ptr LargeSceneryPlaceAction::Query() const
log_error(
"Invalid game command for scenery placement, primaryColour = %u, secondaryColour = %u", _primaryColour,
_secondaryColour);
return std::make_unique<LargeSceneryPlaceActionResult>(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE);
}
if (_sceneryType >= MAX_LARGE_SCENERY_OBJECTS)
{
log_error("Invalid game command for scenery placement, sceneryType = %u", _sceneryType);
return std::make_unique<LargeSceneryPlaceActionResult>(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE);
}
auto* sceneryEntry = get_large_scenery_entry(_sceneryType);
if (sceneryEntry == nullptr)
{
log_error("Invalid game command for scenery placement, sceneryType = %u", _sceneryType);
return std::make_unique<LargeSceneryPlaceActionResult>(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE);
}
uint32_t totalNumTiles = GetTotalNumTiles(sceneryEntry->tiles);
@ -148,45 +129,47 @@ GameActions::Result::Ptr LargeSceneryPlaceAction::Query() const
{
if ((canBuild->GroundFlags & ELEMENT_IS_UNDERWATER) || (canBuild->GroundFlags & ELEMENT_IS_UNDERGROUND))
{
return std::make_unique<LargeSceneryPlaceActionResult>(
GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_UNDERWATER);
return MakeResult(GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_CANT_BUILD_THIS_UNDERWATER);
}
if (res->GroundFlags && !(res->GroundFlags & tempSceneryGroundFlags))
if (resultData.GroundFlags && !(resultData.GroundFlags & tempSceneryGroundFlags))
{
return std::make_unique<LargeSceneryPlaceActionResult>(
GameActions::Status::Disallowed, STR_CANT_BUILD_PARTLY_ABOVE_AND_PARTLY_BELOW_GROUND);
return MakeResult(
GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE,
STR_CANT_BUILD_PARTLY_ABOVE_AND_PARTLY_BELOW_GROUND);
}
}
res->GroundFlags = tempSceneryGroundFlags;
resultData.GroundFlags = tempSceneryGroundFlags;
if (!LocationValid(curTile) || map_is_edge(curTile))
{
return std::make_unique<LargeSceneryPlaceActionResult>(GameActions::Status::Disallowed, STR_OFF_EDGE_OF_MAP);
return MakeResult(GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_OFF_EDGE_OF_MAP);
}
if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !map_is_location_owned({ curTile, zLow }) && !gCheatsSandboxMode)
{
return std::make_unique<LargeSceneryPlaceActionResult>(GameActions::Status::Disallowed, STR_LAND_NOT_OWNED_BY_PARK);
return MakeResult(GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK);
}
}
if (!CheckMapCapacity(sceneryEntry->tiles, totalNumTiles))
{
log_error("No free map elements available");
return std::make_unique<LargeSceneryPlaceActionResult>(GameActions::Status::NoFreeElements);
return MakeResult(GameActions::Status::NoFreeElements, STR_CANT_POSITION_THIS_HERE, STR_TILE_ELEMENT_LIMIT_REACHED);
}
// Force ride construction to recheck area
_currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK;
res->Cost = (sceneryEntry->price * 10) + supportsCost;
res->SetData(std::move(resultData));
return res;
}
GameActions::Result::Ptr LargeSceneryPlaceAction::Execute() const
{
auto res = std::make_unique<LargeSceneryPlaceActionResult>();
auto res = MakeResult();
res->ErrorTitle = STR_CANT_POSITION_THIS_HERE;
res->Expenditure = ExpenditureType::Landscaping;
@ -194,7 +177,8 @@ GameActions::Result::Ptr LargeSceneryPlaceAction::Execute() const
res->Position.x = _loc.x + 16;
res->Position.y = _loc.y + 16;
res->Position.z = surfaceHeight;
res->GroundFlags = 0;
auto resultData = LargeSceneryPlaceActionResult{};
money32 supportsCost = 0;
@ -202,13 +186,13 @@ GameActions::Result::Ptr LargeSceneryPlaceAction::Execute() const
if (sceneryEntry == nullptr)
{
log_error("Invalid game command for scenery placement, sceneryType = %u", _sceneryType);
return std::make_unique<LargeSceneryPlaceActionResult>(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE);
}
if (sceneryEntry->tiles == nullptr)
{
log_error("Invalid large scenery object, sceneryType = %u", _sceneryType);
return std::make_unique<LargeSceneryPlaceActionResult>(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE);
}
int16_t maxHeight = GetMaxSurfaceHeight(sceneryEntry->tiles);
@ -228,7 +212,8 @@ GameActions::Result::Ptr LargeSceneryPlaceAction::Execute() const
if (banner == nullptr)
{
log_error("No free banners available");
return MakeResult(GameActions::Status::InvalidParameters, STR_TOO_MANY_BANNERS_IN_GAME);
return MakeResult(
GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_TOO_MANY_BANNERS_IN_GAME);
}
banner->text = {};
@ -245,7 +230,7 @@ GameActions::Result::Ptr LargeSceneryPlaceAction::Execute() const
banner->flags |= BANNER_FLAG_LINKED_TO_RIDE;
}
res->bannerId = banner->id;
resultData.bannerId = banner->id;
}
uint8_t tileNum = 0;
@ -275,7 +260,7 @@ GameActions::Result::Ptr LargeSceneryPlaceAction::Execute() const
}
supportsCost += canBuild->Cost;
res->GroundFlags = canBuild->GroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND);
resultData.GroundFlags = canBuild->GroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND);
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST))
{
@ -302,7 +287,7 @@ GameActions::Result::Ptr LargeSceneryPlaceAction::Execute() const
if (tileNum == 0)
{
res->firstTileHeight = zLow;
resultData.firstTileHeight = zLow;
}
}
@ -310,6 +295,8 @@ GameActions::Result::Ptr LargeSceneryPlaceAction::Execute() const
_currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK;
res->Cost = (sceneryEntry->price * 10) + supportsCost;
res->SetData(std::move(resultData));
return res;
}

View File

@ -13,20 +13,14 @@
#include "../world/Scenery.h"
#include "GameAction.h"
class LargeSceneryPlaceActionResult final : public GameActions::Result
struct LargeSceneryPlaceActionResult
{
public:
LargeSceneryPlaceActionResult();
LargeSceneryPlaceActionResult(GameActions::Status error);
LargeSceneryPlaceActionResult(GameActions::Status error, rct_string_id message);
LargeSceneryPlaceActionResult(GameActions::Status error, rct_string_id message, uint8_t* args);
uint8_t GroundFlags{ 0 };
int32_t firstTileHeight{ 0 };
BannerIndex bannerId = BANNER_INDEX_NULL;
};
DEFINE_GAME_ACTION(LargeSceneryPlaceAction, GameCommand::PlaceLargeScenery, LargeSceneryPlaceActionResult)
DEFINE_GAME_ACTION(LargeSceneryPlaceAction, GameCommand::PlaceLargeScenery, GameActions::Result)
{
private:
CoordsXYZD _loc;

View File

@ -27,16 +27,6 @@
#include <algorithm>
RideCreateGameActionResult::RideCreateGameActionResult()
: GameActions::Result(GameActions::Status::Ok, STR_NONE)
{
}
RideCreateGameActionResult::RideCreateGameActionResult(GameActions::Status error, rct_string_id message)
: GameActions::Result(error, STR_CANT_CREATE_NEW_RIDE_ATTRACTION, message)
{
}
RideCreateAction::RideCreateAction(int32_t rideType, ObjectEntryIndex subType, int32_t colour1, int32_t colour2)
: _rideType(rideType)
, _subType(subType)
@ -81,39 +71,42 @@ GameActions::Result::Ptr RideCreateAction::Query() const
if (rideIndex == RIDE_ID_NULL)
{
// No more free slots available.
return MakeResult(GameActions::Status::NoFreeElements, STR_TOO_MANY_RIDES);
return MakeResult(GameActions::Status::NoFreeElements, STR_CANT_CREATE_NEW_RIDE_ATTRACTION, STR_TOO_MANY_RIDES);
}
if (_rideType >= RIDE_TYPE_COUNT)
{
return MakeResult(GameActions::Status::InvalidParameters, STR_INVALID_RIDE_TYPE);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_CREATE_NEW_RIDE_ATTRACTION, STR_INVALID_RIDE_TYPE);
}
int32_t rideEntryIndex = ride_get_entry_index(_rideType, _subType);
if (rideEntryIndex >= MAX_RIDE_OBJECTS)
{
return MakeResult(GameActions::Status::InvalidParameters, STR_INVALID_RIDE_TYPE);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_CREATE_NEW_RIDE_ATTRACTION, STR_INVALID_RIDE_TYPE);
}
const auto& colourPresets = GetRideTypeDescriptor(_rideType).ColourPresets;
if (_colour1 >= colourPresets.count)
{
return MakeResult(GameActions::Status::InvalidParameters, STR_NONE);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_CREATE_NEW_RIDE_ATTRACTION, STR_NONE);
}
rct_ride_entry* rideEntry = get_ride_entry(rideEntryIndex);
if (rideEntry == nullptr)
{
return MakeResult(GameActions::Status::InvalidParameters, STR_NONE);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_CREATE_NEW_RIDE_ATTRACTION, STR_NONE);
}
vehicle_colour_preset_list* presetList = rideEntry->vehicle_preset_list;
if ((presetList->count > 0 && presetList->count != 255) && _colour2 >= presetList->count)
{
return MakeResult(GameActions::Status::InvalidParameters, STR_NONE);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_CREATE_NEW_RIDE_ATTRACTION, STR_NONE);
}
return MakeResult();
auto res = MakeResult();
res->SetData(ride_id_t{ rideIndex });
return res;
}
GameActions::Result::Ptr RideCreateAction::Execute() const
@ -124,16 +117,12 @@ GameActions::Result::Ptr RideCreateAction::Execute() const
int32_t rideEntryIndex = ride_get_entry_index(_rideType, _subType);
auto rideIndex = GetNextFreeRideId();
res->rideIndex = rideIndex;
auto ride = GetOrAllocateRide(rideIndex);
rideEntry = get_ride_entry(rideEntryIndex);
if (rideEntry == nullptr)
{
log_warning("Invalid request for ride %u", rideIndex);
res->Error = GameActions::Status::Unknown;
res->ErrorMessage = STR_UNKNOWN_OBJECT_TYPE;
return res;
return MakeResult(GameActions::Status::Unknown, STR_CANT_CREATE_NEW_RIDE_ATTRACTION, STR_UNKNOWN_OBJECT_TYPE);
}
ride->id = rideIndex;
@ -315,6 +304,7 @@ GameActions::Result::Ptr RideCreateAction::Execute() const
window_invalidate_by_class(WC_RIDE_LIST);
res->Expenditure = ExpenditureType::RideConstruction;
res->SetData(ride_id_t{ rideIndex });
return res;
}

View File

@ -11,16 +11,7 @@
#include "GameAction.h"
class RideCreateGameActionResult final : public GameActions::Result
{
public:
RideCreateGameActionResult();
RideCreateGameActionResult(GameActions::Status error, rct_string_id message);
ride_id_t rideIndex = RIDE_ID_NULL;
};
DEFINE_GAME_ACTION(RideCreateAction, GameCommand::CreateRide, RideCreateGameActionResult)
DEFINE_GAME_ACTION(RideCreateAction, GameCommand::CreateRide, GameActions::Result)
{
private:
ObjectEntryIndex _rideType{ OBJECT_ENTRY_INDEX_NULL };

View File

@ -27,26 +27,6 @@
#include "GameAction.h"
#include "SmallSceneryRemoveAction.h"
SmallSceneryPlaceActionResult::SmallSceneryPlaceActionResult()
: GameActions::Result(GameActions::Status::Ok, STR_CANT_POSITION_THIS_HERE)
{
}
SmallSceneryPlaceActionResult::SmallSceneryPlaceActionResult(GameActions::Status error)
: GameActions::Result(error, STR_CANT_POSITION_THIS_HERE)
{
}
SmallSceneryPlaceActionResult::SmallSceneryPlaceActionResult(GameActions::Status error, rct_string_id message)
: GameActions::Result(error, STR_CANT_POSITION_THIS_HERE, message)
{
}
SmallSceneryPlaceActionResult::SmallSceneryPlaceActionResult(GameActions::Status error, rct_string_id message, uint8_t* args)
: GameActions::Result(error, STR_CANT_POSITION_THIS_HERE, message, args)
{
}
SmallSceneryPlaceAction::SmallSceneryPlaceAction(
const CoordsXYZD& loc, uint8_t quadrant, ObjectEntryIndex sceneryType, uint8_t primaryColour, uint8_t secondaryColour)
: _loc(loc)
@ -100,7 +80,7 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const
{
surfaceHeight = waterHeight;
}
auto res = std::make_unique<SmallSceneryPlaceActionResult>();
auto res = MakeResult();
auto centre = _loc.ToTileCentre();
res->Position.x = centre.x;
res->Position.y = centre.y;
@ -113,31 +93,30 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const
if (!LocationValid(_loc))
{
return MakeResult(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE);
}
if (!MapCheckCapacityAndReorganise(_loc))
{
return std::make_unique<SmallSceneryPlaceActionResult>(GameActions::Status::NoFreeElements);
return MakeResult(GameActions::Status::NoFreeElements, STR_CANT_POSITION_THIS_HERE, STR_TILE_ELEMENT_LIMIT_REACHED);
}
if (!_trackDesignDrawingPreview && (_loc.x > GetMapSizeMaxXY() || _loc.y > GetMapSizeMaxXY()))
{
return std::make_unique<SmallSceneryPlaceActionResult>(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE);
}
auto* sceneryEntry = get_small_scenery_entry(_sceneryType);
if (sceneryEntry == nullptr)
{
return std::make_unique<SmallSceneryPlaceActionResult>(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE);
}
auto quadrant = _quadrant;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE)
|| !scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_DIAGONAL))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE) || !sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_DIAGONAL))
{
if (scenery_small_entry_has_flag(
sceneryEntry, SMALL_SCENERY_FLAG_DIAGONAL | SMALL_SCENERY_FLAG_HALF_SPACE | SMALL_SCENERY_FLAG_THREE_QUARTERS))
if (sceneryEntry->HasFlag(
SMALL_SCENERY_FLAG_DIAGONAL | SMALL_SCENERY_FLAG_HALF_SPACE | SMALL_SCENERY_FLAG_THREE_QUARTERS))
{
quadrant = 0;
}
@ -145,7 +124,7 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const
// Check if sub tile height is any different compared to actual surface tile height
auto loc2 = _loc;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE))
{
loc2 = loc2.ToTileCentre();
}
@ -177,7 +156,7 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const
if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode
&& !map_is_location_owned({ _loc.x, _loc.y, targetHeight }))
{
return std::make_unique<SmallSceneryPlaceActionResult>(GameActions::Status::NotOwned, STR_LAND_NOT_OWNED_BY_PARK);
return MakeResult(GameActions::Status::NotOwned, STR_CANT_POSITION_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK);
}
auto* surfaceElement = map_get_surface_element_at(_loc);
@ -187,38 +166,34 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const
int32_t water_height = surfaceElement->GetWaterHeight() - 1;
if (water_height > targetHeight)
{
return std::make_unique<SmallSceneryPlaceActionResult>(
GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_UNDERWATER);
return MakeResult(GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_CANT_BUILD_THIS_UNDERWATER);
}
}
if (!gCheatsDisableClearanceChecks && !(scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_STACKABLE)))
if (!gCheatsDisableClearanceChecks && !(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_STACKABLE)))
{
if (isOnWater)
{
return std::make_unique<SmallSceneryPlaceActionResult>(
GameActions::Status::Disallowed, STR_CAN_ONLY_BUILD_THIS_ON_LAND);
return MakeResult(GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ON_LAND);
}
if (surfaceElement != nullptr && surfaceElement->GetWaterHeight() > 0)
{
if (surfaceElement->GetWaterHeight() > targetHeight)
{
return std::make_unique<SmallSceneryPlaceActionResult>(
GameActions::Status::Disallowed, STR_CAN_ONLY_BUILD_THIS_ON_LAND);
return MakeResult(
GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ON_LAND);
}
}
}
if (!gCheatsDisableClearanceChecks && (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_REQUIRE_FLAT_SURFACE))
&& !supportsRequired && !isOnWater && surfaceElement != nullptr
&& (surfaceElement->GetSlope() != TILE_ELEMENT_SLOPE_FLAT))
if (!gCheatsDisableClearanceChecks && (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_REQUIRE_FLAT_SURFACE)) && !supportsRequired
&& !isOnWater && surfaceElement != nullptr && (surfaceElement->GetSlope() != TILE_ELEMENT_SLOPE_FLAT))
{
return std::make_unique<SmallSceneryPlaceActionResult>(GameActions::Status::Disallowed, STR_LEVEL_LAND_REQUIRED);
return MakeResult(GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_LEVEL_LAND_REQUIRED);
}
if (!gCheatsDisableSupportLimits && !(scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_STACKABLE))
&& supportsRequired)
if (!gCheatsDisableSupportLimits && !(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_STACKABLE)) && supportsRequired)
{
if (!isOnWater)
{
@ -226,15 +201,13 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const
{
if (surfaceElement->GetWaterHeight() > 0 || (surfaceElement->GetBaseZ()) != targetHeight)
{
return std::make_unique<SmallSceneryPlaceActionResult>(
GameActions::Status::Disallowed, STR_LEVEL_LAND_REQUIRED);
return MakeResult(GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_LEVEL_LAND_REQUIRED);
}
}
}
else
{
return std::make_unique<SmallSceneryPlaceActionResult>(
GameActions::Status::Disallowed, STR_CAN_ONLY_BUILD_THIS_ON_LAND);
return MakeResult(GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ON_LAND);
}
}
@ -242,17 +215,16 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const
int32_t zHigh = zLow + ceil2(sceneryEntry->height, COORDS_Z_STEP);
uint8_t collisionQuadrants = 0b1111;
auto quadRotation{ 0 };
if (!(scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE)))
if (!(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE)))
{
quadRotation = (quadrant ^ 2);
collisionQuadrants = 0b0001;
}
if (!(scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_HALF_SPACE)))
if (!(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_HALF_SPACE)))
{
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_DIAGONAL)
&& scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_DIAGONAL) && sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE))
{
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_THREE_QUARTERS))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_THREE_QUARTERS))
{
quadRotation = ((quadrant ^ 2) + _loc.direction) & 3;
collisionQuadrants = 0b1011;
@ -276,7 +248,7 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const
}
QuarterTile quarterTile = QuarterTile{ collisionQuadrants, supports }.Rotate(quadRotation);
const auto isTree = scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_IS_TREE);
const auto isTree = sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_IS_TREE);
auto canBuild = MapCanConstructWithClearAt(
{ _loc, zLow, zHigh }, &map_place_scenery_clear_func, quarterTile, GetFlags(), CREATE_CROSSING_MODE_NONE, isTree);
if (canBuild->Error != GameActions::Status::Ok)
@ -285,7 +257,8 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const
return canBuild;
}
res->GroundFlags = canBuild->GroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND);
const uint8_t groundFlags = canBuild->GroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND);
res->SetData(SmallSceneryPlaceActionResult{ groundFlags, 0, 0 });
res->Expenditure = ExpenditureType::Landscaping;
res->Cost = (sceneryEntry->price * 10) + canBuild->Cost;
@ -309,7 +282,7 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Execute() const
{
surfaceHeight = waterHeight;
}
auto res = std::make_unique<SmallSceneryPlaceActionResult>();
auto res = MakeResult();
auto centre = _loc.ToTileCentre();
res->Position.x = centre.x;
res->Position.y = centre.y;
@ -323,15 +296,14 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Execute() const
auto* sceneryEntry = get_small_scenery_entry(_sceneryType);
if (sceneryEntry == nullptr)
{
return std::make_unique<SmallSceneryPlaceActionResult>(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE);
}
auto quadrant = _quadrant;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE)
|| !scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_DIAGONAL))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE) || !sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_DIAGONAL))
{
if (scenery_small_entry_has_flag(
sceneryEntry, SMALL_SCENERY_FLAG_DIAGONAL | SMALL_SCENERY_FLAG_HALF_SPACE | SMALL_SCENERY_FLAG_THREE_QUARTERS))
if (sceneryEntry->HasFlag(
SMALL_SCENERY_FLAG_DIAGONAL | SMALL_SCENERY_FLAG_HALF_SPACE | SMALL_SCENERY_FLAG_THREE_QUARTERS))
{
quadrant = 0;
}
@ -340,7 +312,7 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Execute() const
// Check if sub tile height is any different compared to actual surface tile height
int32_t x2 = _loc.x;
int32_t y2 = _loc.y;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE))
{
x2 += 16;
y2 += 16;
@ -369,7 +341,7 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Execute() const
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST))
{
footpath_remove_litter({ _loc, targetHeight });
if (!gCheatsDisableClearanceChecks && (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_NO_WALLS)))
if (!gCheatsDisableClearanceChecks && (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_NO_WALLS)))
{
wall_remove_at({ _loc, targetHeight, targetHeight + sceneryEntry->height });
}
@ -379,17 +351,16 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Execute() const
int32_t zHigh = zLow + ceil2(sceneryEntry->height, 8);
uint8_t collisionQuadrants = 0b1111;
auto quadRotation{ 0 };
if (!(scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE)))
if (!(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE)))
{
quadRotation = (quadrant ^ 2);
collisionQuadrants = 0b0001;
}
if (!(scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_HALF_SPACE)))
if (!(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_HALF_SPACE)))
{
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_DIAGONAL)
&& scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_DIAGONAL) && sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE))
{
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_THREE_QUARTERS))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_THREE_QUARTERS))
{
quadRotation = ((quadrant ^ 2) + _loc.direction) & 3;
collisionQuadrants = 0b1011;
@ -413,7 +384,7 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Execute() const
}
QuarterTile quarterTile = QuarterTile{ collisionQuadrants, supports }.Rotate(quadRotation);
const auto isTree = scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_IS_TREE);
const auto isTree = sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_IS_TREE);
auto canBuild = MapCanConstructWithClearAt(
{ _loc, zLow, zHigh }, &map_place_scenery_clear_func, quarterTile, GetFlags() | GAME_COMMAND_FLAG_APPLY,
CREATE_CROSSING_MODE_NONE, isTree);
@ -423,14 +394,15 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Execute() const
return canBuild;
}
res->GroundFlags = canBuild->GroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND);
res->Expenditure = ExpenditureType::Landscaping;
res->Cost = (sceneryEntry->price * 10) + canBuild->Cost;
auto* sceneryElement = TileElementInsert<SmallSceneryElement>(
CoordsXYZ{ _loc, zLow }, quarterTile.GetBaseQuarterOccupied());
Guard::Assert(sceneryElement != nullptr);
if (sceneryElement == nullptr)
{
return MakeResult(GameActions::Status::NoFreeElements, STR_CANT_POSITION_THIS_HERE, STR_TILE_ELEMENT_LIMIT_REACHED);
}
sceneryElement->SetDirection(_loc.direction);
sceneryElement->SetSceneryQuadrant(quadrant);
@ -445,10 +417,12 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Execute() const
sceneryElement->SetNeedsSupports();
}
res->tileElement = sceneryElement->as<TileElement>();
const uint8_t groundFlags = canBuild->GroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND);
res->SetData(
SmallSceneryPlaceActionResult{ groundFlags, sceneryElement->GetBaseZ(), sceneryElement->GetSceneryQuadrant() });
map_invalidate_tile_full(_loc);
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_ANIMATED))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_ANIMATED))
{
map_animation_create(MAP_ANIMATION_TYPE_SMALL_SCENERY, CoordsXYZ{ _loc, sceneryElement->GetBaseZ() });
}

View File

@ -12,19 +12,14 @@
#include "../world/TileElement.h"
#include "GameAction.h"
class SmallSceneryPlaceActionResult final : public GameActions::Result
struct SmallSceneryPlaceActionResult
{
public:
SmallSceneryPlaceActionResult();
SmallSceneryPlaceActionResult(GameActions::Status error);
SmallSceneryPlaceActionResult(GameActions::Status error, rct_string_id message);
SmallSceneryPlaceActionResult(GameActions::Status error, rct_string_id message, uint8_t* args);
uint8_t GroundFlags{ 0 };
TileElement* tileElement = nullptr;
uint8_t GroundFlags{};
int32_t BaseHeight{};
uint8_t SceneryQuadrant{};
};
DEFINE_GAME_ACTION(SmallSceneryPlaceAction, GameCommand::PlaceScenery, SmallSceneryPlaceActionResult)
DEFINE_GAME_ACTION(SmallSceneryPlaceAction, GameCommand::PlaceScenery, GameActions::Result)
{
private:
CoordsXYZD _loc;

View File

@ -76,7 +76,7 @@ GameActions::Result::Ptr SmallSceneryRemoveAction::Query() const
// Check if allowed to remove item
if (gParkFlags & PARK_FLAGS_FORBID_TREE_REMOVAL)
{
if (scenery_small_entry_has_flag(entry, SMALL_SCENERY_FLAG_IS_TREE))
if (entry->HasFlag(SMALL_SCENERY_FLAG_IS_TREE))
{
res->Error = GameActions::Status::NoClearance;
res->ErrorTitle = STR_CANT_REMOVE_THIS;

View File

@ -26,15 +26,13 @@
#include "../world/Park.h"
#include "../world/Sprite.h"
StaffHireNewActionResult::StaffHireNewActionResult()
: GameActions::Result(GameActions::Status::Ok, STR_CANT_HIRE_NEW_STAFF)
{
}
StaffHireNewActionResult::StaffHireNewActionResult(GameActions::Status error, rct_string_id message)
: GameActions::Result(error, STR_CANT_HIRE_NEW_STAFF, message)
{
}
/* rct2: 0x009929FC */
static constexpr const PeepSpriteType spriteTypes[] = {
PeepSpriteType::Handyman,
PeepSpriteType::Mechanic,
PeepSpriteType::Security,
PeepSpriteType::EntertainerPanda,
};
StaffHireNewAction::StaffHireNewAction(
bool autoPosition, StaffType staffType, EntertainerCostume entertainerType, uint32_t staffOrders)
@ -77,8 +75,7 @@ GameActions::Result::Ptr StaffHireNewAction::Execute() const
GameActions::Result::Ptr StaffHireNewAction::QueryExecute(bool execute) const
{
auto res = std::make_unique<StaffHireNewActionResult>();
auto res = MakeResult();
res->Expenditure = ExpenditureType::Wages;
if (_staffType >= static_cast<uint8_t>(StaffType::Count))
@ -86,12 +83,12 @@ GameActions::Result::Ptr StaffHireNewAction::QueryExecute(bool execute) const
// Invalid staff type.
log_error("Tried to use invalid staff type: %u", static_cast<uint32_t>(_staffType));
return MakeResult(GameActions::Status::InvalidParameters, STR_NONE);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_HIRE_NEW_STAFF, STR_NONE);
}
if (GetNumFreeEntities() < 400)
{
return MakeResult(GameActions::Status::NoFreeElements, STR_TOO_MANY_PEOPLE_IN_GAME);
return MakeResult(GameActions::Status::NoFreeElements, STR_CANT_HIRE_NEW_STAFF, STR_TOO_MANY_PEOPLE_IN_GAME);
}
if (_staffType == static_cast<uint8_t>(StaffType::Entertainer))
@ -101,7 +98,7 @@ GameActions::Result::Ptr StaffHireNewAction::QueryExecute(bool execute) const
// Invalid entertainer costume
log_error("Tried to use invalid entertainer type: %u", static_cast<uint32_t>(_entertainerType));
return MakeResult(GameActions::Status::InvalidParameters, STR_NONE);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_HIRE_NEW_STAFF, STR_NONE);
}
uint32_t availableCostumes = staff_get_available_entertainer_costumes();
@ -110,7 +107,7 @@ GameActions::Result::Ptr StaffHireNewAction::QueryExecute(bool execute) const
// Entertainer costume unavailable
log_error("Tried to use unavailable entertainer type: %u", static_cast<uint32_t>(_entertainerType));
return MakeResult(GameActions::Status::InvalidParameters, STR_NONE);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_HIRE_NEW_STAFF, STR_NONE);
}
}
@ -118,13 +115,15 @@ GameActions::Result::Ptr StaffHireNewAction::QueryExecute(bool execute) const
if (newPeep == nullptr)
{
// Too many peeps exist already.
return MakeResult(GameActions::Status::NoFreeElements, STR_TOO_MANY_PEOPLE_IN_GAME);
return MakeResult(GameActions::Status::NoFreeElements, STR_CANT_HIRE_NEW_STAFF, STR_TOO_MANY_PEOPLE_IN_GAME);
}
if (execute == false)
{
// In query we just want to see if we can obtain a sprite slot.
sprite_remove(newPeep);
res->SetData(StaffHireNewActionResult{ SPRITE_INDEX_NULL });
}
else
{
@ -211,7 +210,7 @@ GameActions::Result::Ptr StaffHireNewAction::QueryExecute(bool execute) const
newPeep->PatrolInfo = nullptr;
res->peepSriteIndex = newPeep->sprite_index;
res->SetData(StaffHireNewActionResult{ newPeep->sprite_index });
}
return res;

View File

@ -12,24 +12,12 @@
#include "../peep/Staff.h"
#include "GameAction.h"
/* rct2: 0x009929FC */
static constexpr const PeepSpriteType spriteTypes[] = {
PeepSpriteType::Handyman,
PeepSpriteType::Mechanic,
PeepSpriteType::Security,
PeepSpriteType::EntertainerPanda,
};
class StaffHireNewActionResult final : public GameActions::Result
struct StaffHireNewActionResult
{
public:
StaffHireNewActionResult();
StaffHireNewActionResult(GameActions::Status error, rct_string_id message);
uint32_t peepSriteIndex = SPRITE_INDEX_NULL;
uint16_t StaffEntityId = SPRITE_INDEX_NULL;
};
DEFINE_GAME_ACTION(StaffHireNewAction, GameCommand::HireNewStaffMember, StaffHireNewActionResult)
DEFINE_GAME_ACTION(StaffHireNewAction, GameCommand::HireNewStaffMember, GameActions::Result)
{
private:
bool _autoPosition{};

View File

@ -103,13 +103,12 @@ GameActions::Result::Ptr TrackDesignAction::Query() const
auto rideCreateAction = RideCreateAction(_td.type, entryIndex, 0, 0);
rideCreateAction.SetFlags(GetFlags());
auto r = GameActions::ExecuteNested(&rideCreateAction);
auto rideIndex = static_cast<RideCreateGameActionResult*>(r.get())->rideIndex;
if (r->Error != GameActions::Status::Ok)
{
return MakeResult(GameActions::Status::NoFreeElements, STR_CANT_CREATE_NEW_RIDE_ATTRACTION, STR_NONE);
}
const auto rideIndex = r->GetData<ride_id_t>();
auto ride = get_ride(rideIndex);
if (ride == nullptr)
{
@ -164,13 +163,12 @@ GameActions::Result::Ptr TrackDesignAction::Execute() const
auto rideCreateAction = RideCreateAction(_td.type, entryIndex, 0, 0);
rideCreateAction.SetFlags(GetFlags());
auto r = GameActions::ExecuteNested(&rideCreateAction);
auto rideIndex = static_cast<RideCreateGameActionResult*>(r.get())->rideIndex;
if (r->Error != GameActions::Status::Ok)
{
return MakeResult(GameActions::Status::NoFreeElements, STR_CANT_CREATE_NEW_RIDE_ATTRACTION, STR_NONE);
}
const auto rideIndex = r->GetData<ride_id_t>();
auto ride = get_ride(rideIndex);
if (ride == nullptr)
{

View File

@ -21,25 +21,6 @@
#include "../world/Wall.h"
using namespace OpenRCT2::TrackMetaData;
WallPlaceActionResult::WallPlaceActionResult()
: GameActions::Result(GameActions::Status::Ok, STR_CANT_BUILD_THIS_HERE)
{
}
WallPlaceActionResult::WallPlaceActionResult(GameActions::Status err)
: GameActions::Result(err, STR_CANT_BUILD_THIS_HERE)
{
}
WallPlaceActionResult::WallPlaceActionResult(GameActions::Status err, rct_string_id msg)
: GameActions::Result(err, STR_CANT_BUILD_THIS_HERE, msg)
{
}
WallPlaceActionResult::WallPlaceActionResult(GameActions::Status error, rct_string_id msg, uint8_t* args)
: GameActions::Result(error, STR_CANT_BUILD_THIS_HERE, msg, args)
{
}
WallPlaceAction::WallPlaceAction(
ObjectEntryIndex wallType, const CoordsXYZ& loc, uint8_t edge, int32_t primaryColour, int32_t secondaryColour,
@ -78,7 +59,7 @@ void WallPlaceAction::Serialise(DataSerialiser& stream)
GameActions::Result::Ptr WallPlaceAction::Query() const
{
auto res = std::make_unique<WallPlaceActionResult>();
auto res = MakeResult();
res->ErrorTitle = STR_CANT_BUILD_THIS_HERE;
res->Position = _loc;
@ -93,7 +74,7 @@ GameActions::Result::Ptr WallPlaceAction::Query() const
if (!LocationValid(_loc))
{
return MakeResult(GameActions::Status::NotOwned);
return MakeResult(GameActions::Status::NotOwned, STR_CANT_BUILD_THIS_HERE, STR_NONE);
}
if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !(GetFlags() & GAME_COMMAND_FLAG_PATH_SCENERY) && !gCheatsSandboxMode)
@ -102,23 +83,23 @@ GameActions::Result::Ptr WallPlaceAction::Query() const
{
if (!map_is_location_in_park(_loc))
{
return std::make_unique<WallPlaceActionResult>(GameActions::Status::NotOwned);
return MakeResult(GameActions::Status::NotOwned, STR_CANT_BUILD_THIS_HERE, STR_NONE);
}
}
else if (!map_is_location_owned(_loc))
{
return std::make_unique<WallPlaceActionResult>(GameActions::Status::NotOwned);
return MakeResult(GameActions::Status::NotOwned, STR_CANT_BUILD_THIS_HERE, STR_NONE);
}
}
else if (!_trackDesignDrawingPreview && (_loc.x > GetMapSizeMaxXY() || _loc.y > GetMapSizeMaxXY()))
{
log_error("Invalid x/y coordinates. x = %d y = %d", _loc.x, _loc.y);
return std::make_unique<WallPlaceActionResult>(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_BUILD_THIS_HERE, STR_NONE);
}
if (_edge > 3)
{
return std::make_unique<WallPlaceActionResult>(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_BUILD_THIS_HERE, STR_NONE);
}
uint8_t edgeSlope = 0;
@ -129,7 +110,7 @@ GameActions::Result::Ptr WallPlaceAction::Query() const
if (surfaceElement == nullptr)
{
log_error("Surface element not found at %d, %d.", _loc.x, _loc.y);
return std::make_unique<WallPlaceActionResult>(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_BUILD_THIS_HERE, STR_NONE);
}
targetHeight = surfaceElement->GetBaseZ();
@ -146,7 +127,7 @@ GameActions::Result::Ptr WallPlaceAction::Query() const
if (surfaceElement == nullptr)
{
log_error("Surface element not found at %d, %d.", _loc.x, _loc.y);
return std::make_unique<WallPlaceActionResult>(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_BUILD_THIS_HERE, STR_NONE);
}
if (surfaceElement->GetWaterHeight() > 0)
@ -155,13 +136,13 @@ GameActions::Result::Ptr WallPlaceAction::Query() const
if (targetHeight < waterHeight && !gCheatsDisableClearanceChecks)
{
return std::make_unique<WallPlaceActionResult>(GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_UNDERWATER);
return MakeResult(GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_HERE, STR_CANT_BUILD_THIS_UNDERWATER);
}
}
if (targetHeight < surfaceElement->GetBaseZ() && !gCheatsDisableClearanceChecks)
{
return std::make_unique<WallPlaceActionResult>(GameActions::Status::Disallowed, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND);
return MakeResult(GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND);
}
if (!(edgeSlope & (EDGE_SLOPE_UPWARDS | EDGE_SLOPE_DOWNWARDS)))
@ -173,8 +154,8 @@ GameActions::Result::Ptr WallPlaceAction::Query() const
{
if (targetHeight / 8 < newBaseHeight)
{
return std::make_unique<WallPlaceActionResult>(
GameActions::Status::Disallowed, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND);
return MakeResult(
GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND);
}
if (surfaceElement->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
@ -189,8 +170,9 @@ GameActions::Result::Ptr WallPlaceAction::Query() const
newBaseHeight += 2;
if (targetHeight / 8 < newBaseHeight)
{
return std::make_unique<WallPlaceActionResult>(
GameActions::Status::Disallowed, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND);
return MakeResult(
GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_HERE,
STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND);
}
newBaseHeight -= 2;
}
@ -203,8 +185,8 @@ GameActions::Result::Ptr WallPlaceAction::Query() const
{
if (targetHeight / 8 < newBaseHeight)
{
return std::make_unique<WallPlaceActionResult>(
GameActions::Status::Disallowed, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND);
return MakeResult(
GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND);
}
if (surfaceElement->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
@ -219,8 +201,9 @@ GameActions::Result::Ptr WallPlaceAction::Query() const
newBaseHeight += 2;
if (targetHeight / 8 < newBaseHeight)
{
return std::make_unique<WallPlaceActionResult>(
GameActions::Status::Disallowed, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND);
return MakeResult(
GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_HERE,
STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND);
}
}
}
@ -233,7 +216,7 @@ GameActions::Result::Ptr WallPlaceAction::Query() const
if (wallEntry == nullptr)
{
log_error("Wall Type not found %d", _wallType);
return std::make_unique<WallPlaceActionResult>(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_BUILD_THIS_HERE, STR_NONE);
}
if (wallEntry->scrolling_mode != SCROLLING_MODE_NONE)
@ -241,7 +224,7 @@ GameActions::Result::Ptr WallPlaceAction::Query() const
if (HasReachedBannerLimit())
{
log_error("No free banners available");
return MakeResult(GameActions::Status::InvalidParameters, STR_TOO_MANY_BANNERS_IN_GAME);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_BUILD_THIS_HERE, STR_TOO_MANY_BANNERS_IN_GAME);
}
}
@ -250,8 +233,7 @@ GameActions::Result::Ptr WallPlaceAction::Query() const
{
if (wallEntry->flags & WALL_SCENERY_CANT_BUILD_ON_SLOPE)
{
return std::make_unique<WallPlaceActionResult>(
GameActions::Status::Disallowed, STR_ERR_UNABLE_TO_BUILD_THIS_ON_SLOPE);
return MakeResult(GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_HERE, STR_ERR_UNABLE_TO_BUILD_THIS_ON_SLOPE);
}
clearanceHeight += 2;
}
@ -269,16 +251,19 @@ GameActions::Result::Ptr WallPlaceAction::Query() const
if (!MapCheckCapacityAndReorganise(_loc))
{
return MakeResult(GameActions::Status::NoFreeElements, STR_TILE_ELEMENT_LIMIT_REACHED);
return MakeResult(GameActions::Status::NoFreeElements, STR_CANT_BUILD_THIS_HERE, STR_TILE_ELEMENT_LIMIT_REACHED);
}
res->Cost = wallEntry->price;
res->SetData(WallPlaceActionResult{});
return res;
}
GameActions::Result::Ptr WallPlaceAction::Execute() const
{
auto res = std::make_unique<WallPlaceActionResult>();
auto res = MakeResult();
res->ErrorTitle = STR_CANT_BUILD_THIS_HERE;
res->Position = _loc;
@ -299,7 +284,7 @@ GameActions::Result::Ptr WallPlaceAction::Execute() const
if (surfaceElement == nullptr)
{
log_error("Surface element not found at %d, %d.", _loc.x, _loc.y);
return std::make_unique<WallPlaceActionResult>(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_BUILD_THIS_HERE, STR_NONE);
}
targetHeight = surfaceElement->GetBaseZ();
@ -318,7 +303,7 @@ GameActions::Result::Ptr WallPlaceAction::Execute() const
if (wallEntry == nullptr)
{
log_error("Wall Type not found %d", _wallType);
return std::make_unique<WallPlaceActionResult>(GameActions::Status::InvalidParameters);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_BUILD_THIS_HERE, STR_NONE);
}
uint8_t clearanceHeight = targetHeight / COORDS_Z_STEP;
@ -345,7 +330,7 @@ GameActions::Result::Ptr WallPlaceAction::Execute() const
if (banner == nullptr)
{
log_error("No free banners available");
return MakeResult(GameActions::Status::InvalidParameters, STR_TOO_MANY_BANNERS_IN_GAME);
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_BUILD_THIS_HERE, STR_TOO_MANY_BANNERS_IN_GAME);
}
banner->text = {};
@ -361,12 +346,13 @@ GameActions::Result::Ptr WallPlaceAction::Execute() const
banner->ride_index = rideIndex;
banner->flags |= BANNER_FLAG_LINKED_TO_RIDE;
}
res->bannerId = banner->id;
}
auto* wallElement = TileElementInsert<WallElement>(targetLoc, 0b0000);
Guard::Assert(wallElement != nullptr);
if (wallElement == nullptr)
{
return MakeResult(GameActions::Status::NoFreeElements, STR_CANT_POSITION_THIS_HERE, STR_TILE_ELEMENT_LIMIT_REACHED);
}
wallElement->clearance_height = clearanceHeight;
wallElement->SetDirection(_edge);
@ -386,12 +372,14 @@ GameActions::Result::Ptr WallPlaceAction::Execute() const
wallElement->SetGhost(GetFlags() & GAME_COMMAND_FLAG_GHOST);
res->tileElement = wallElement->as<TileElement>();
map_animation_create(MAP_ANIMATION_TYPE_WALL, targetLoc);
map_invalidate_tile_zoom1({ _loc, wallElement->GetBaseZ(), wallElement->GetBaseZ() + 72 });
res->Cost = wallEntry->price;
const auto bannerId = banner != nullptr ? banner->id : BANNER_INDEX_NULL;
res->SetData(WallPlaceActionResult{ wallElement->GetBaseZ(), bannerId });
return res;
}
@ -566,7 +554,7 @@ GameActions::Result::Ptr WallPlaceAction::WallCheckObstruction(
case TILE_ELEMENT_TYPE_SMALL_SCENERY:
{
auto sceneryEntry = tileElement->AsSmallScenery()->GetEntry();
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_NO_WALLS))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_NO_WALLS))
{
map_obstruction_set_error_text(tileElement, *res);
return res;

View File

@ -15,19 +15,13 @@
#include "../world/Scenery.h"
#include "GameAction.h"
class WallPlaceActionResult final : public GameActions::Result
struct WallPlaceActionResult
{
public:
WallPlaceActionResult();
WallPlaceActionResult(GameActions::Status err);
WallPlaceActionResult(GameActions::Status err, rct_string_id msg);
WallPlaceActionResult(GameActions::Status error, rct_string_id msg, uint8_t* args);
TileElement* tileElement = nullptr;
BannerIndex bannerId = BANNER_INDEX_NULL;
int32_t BaseHeight{};
BannerIndex BannerId = BANNER_INDEX_NULL;
};
DEFINE_GAME_ACTION(WallPlaceAction, GameCommand::PlaceWall, WallPlaceActionResult)
DEFINE_GAME_ACTION(WallPlaceAction, GameCommand::PlaceWall, GameActions::Result)
{
private:
ObjectEntryIndex _wallType{ OBJECT_ENTRY_INDEX_NULL };

View File

@ -12,14 +12,14 @@
#include <array>
#include <cstddef>
template<typename _TType, size_t _TMax> class CircularBuffer
template<typename TType, size_t TMax> class CircularBuffer
{
public:
using value_type = _TType;
using pointer = _TType*;
using const_pointer = const _TType*;
using reference = _TType&;
using const_reference = const _TType&;
using value_type = TType;
using pointer = TType*;
using const_pointer = const TType*;
using reference = TType&;
using const_reference = const TType&;
using size_type = size_t;
using difference_type = ptrdiff_t;
@ -137,5 +137,5 @@ private:
size_t _head = 0;
size_t _tail = 0;
size_t _size = 0;
std::array<_TType, _TMax> _elements;
std::array<TType, TMax> _elements;
};

View File

@ -16,15 +16,15 @@ namespace Meta
/**
* Meta function for checking that all Conditions are true types.
*/
template<typename... _TConditions> struct all : std::true_type
template<typename... TConditions> struct all : std::true_type
{
};
template<typename _TCondition, typename... _TConditions>
struct all<_TCondition, _TConditions...> : std::conditional<_TCondition::value, all<_TConditions...>, std::false_type>::type
template<typename TCondition, typename... TConditions>
struct all<TCondition, TConditions...> : std::conditional<TCondition::value, all<TConditions...>, std::false_type>::type
{
};
template<typename _TType, typename... _TTypes> using all_convertible = all<std::is_convertible<_TTypes, _TType>...>;
template<typename TType, typename... TTypes> using all_convertible = all<std::is_convertible<TTypes, TType>...>;
} // namespace Meta

View File

@ -27,12 +27,12 @@ namespace Random
/**
* FixedSeedSequence adheres to the _Named Requirement_ `SeedSequence`.
*/
template<size_t _TNum = 0> class FixedSeedSequence
template<size_t TNum = 0> class FixedSeedSequence
{
public:
using result_type = uint32_t;
static constexpr size_t N = _TNum;
static constexpr size_t N = TNum;
static constexpr result_type default_seed = 0x1234567F;
explicit FixedSeedSequence()
@ -41,26 +41,26 @@ namespace Random
}
template<
typename... _TTypes, typename std::enable_if<sizeof...(_TTypes) == N, int>::type = 0,
typename std::enable_if<Meta::all_convertible<result_type, _TTypes...>::value, int>::type = 0>
explicit FixedSeedSequence(_TTypes... s)
typename... TTypes, typename std::enable_if<sizeof...(TTypes) == N, int>::type = 0,
typename std::enable_if<Meta::all_convertible<result_type, TTypes...>::value, int>::type = 0>
explicit FixedSeedSequence(TTypes... s)
: v{ static_cast<result_type>(s)... }
{
}
template<typename _TIt, typename = decltype(*std::declval<_TIt&>(), ++std::declval<_TIt&>(), void())>
explicit FixedSeedSequence(_TIt begin, _TIt end)
template<typename TIt, typename = decltype(*std::declval<TIt&>(), ++std::declval<TIt&>(), void())>
explicit FixedSeedSequence(TIt begin, TIt end)
{
std::copy(begin, end, v.begin());
}
template<typename _TType>
explicit FixedSeedSequence(std::initializer_list<_TType> il)
template<typename TType>
explicit FixedSeedSequence(std::initializer_list<TType> il)
: FixedSeedSequence(il.begin(), il.end())
{
}
template<typename _TIt> void generate(_TIt begin, _TIt end) const
template<typename TIt> void generate(TIt begin, TIt end) const
{
std::copy_n(v.begin(), std::min(static_cast<size_t>(end - begin), N), begin);
}
@ -70,7 +70,7 @@ namespace Random
return N;
}
template<typename _TIt> constexpr void param(_TIt ob) const
template<typename TIt> constexpr void param(TIt ob) const
{
std::copy(v.begin(), v.end(), ob);
}
@ -79,9 +79,9 @@ namespace Random
std::array<result_type, N> v;
};
template<typename _TUIntType> struct RotateEngineState
template<typename TUIntType> struct RotateEngineState
{
using value_type = _TUIntType;
using value_type = TUIntType;
value_type s0;
value_type s1;
@ -91,21 +91,21 @@ namespace Random
* RotateEngine adheres to the _Named Requirement_ `RandomNumberEngine`
* https://en.cppreference.com/w/cpp/named_req/RandomNumberEngine
*/
template<typename _TUIntType, _TUIntType _TX, size_t _TR1, size_t _TR2>
class RotateEngine : protected RotateEngineState<_TUIntType>
template<typename TUIntType, TUIntType TX, size_t TR1, size_t TR2>
class RotateEngine : protected RotateEngineState<TUIntType>
{
static_assert(std::is_unsigned<_TUIntType>::value, "Type must be unsigned integral.");
static_assert(std::is_unsigned<TUIntType>::value, "Type must be unsigned integral.");
using RotateEngineState<_TUIntType>::s0;
using RotateEngineState<_TUIntType>::s1;
using RotateEngineState<TUIntType>::s0;
using RotateEngineState<TUIntType>::s1;
public:
using result_type = _TUIntType;
using state_type = RotateEngineState<_TUIntType>;
using result_type = TUIntType;
using state_type = RotateEngineState<TUIntType>;
static constexpr result_type x = _TX;
static constexpr size_t r1 = _TR1;
static constexpr size_t r2 = _TR2;
static constexpr result_type x = TX;
static constexpr size_t r1 = TR1;
static constexpr size_t r2 = TR2;
static constexpr result_type default_seed = 1;
static constexpr result_type min()
@ -129,8 +129,8 @@ namespace Random
s1 = r.s1;
}
template<typename _TSseq, typename = typename std::enable_if<!std::is_same<_TSseq, RotateEngine>::value>::type>
explicit RotateEngine(_TSseq& seed_seq)
template<typename TSseq, typename = typename std::enable_if<!std::is_same<TSseq, RotateEngine>::value>::type>
explicit RotateEngine(TSseq& seed_seq)
{
seed(seed_seq);
}
@ -141,7 +141,7 @@ namespace Random
s1 = s;
}
template<typename _TSseq> typename std::enable_if<std::is_class<_TSseq>::value, void>::type seed(_TSseq& seed_seq)
template<typename TSseq> typename std::enable_if<std::is_class<TSseq>::value, void>::type seed(TSseq& seed_seq)
{
std::array<result_type, 2> s;
seed_seq.generate(s.begin(), s.end());

View File

@ -33,8 +33,8 @@ enum class FontSpriteBase : int16_t
#ifndef NO_TTF
struct _TTF_Font;
using TTF_Font = _TTF_Font;
struct InternalTTFFont;
using TTF_Font = InternalTTFFont;
struct TTFFontDescriptor
{
const utf8* filename;

View File

@ -103,7 +103,7 @@ struct c_glyph
};
/* The structure used to hold internal font information */
struct _TTF_Font
struct InternalTTFFont
{
/* Freetype2 maintains all sorts of useful info itself */
FT_Face face;

View File

@ -143,7 +143,7 @@ bool WidgetIsPressed(rct_window* w, rct_widgetindex widgetIndex);
bool WidgetIsHighlighted(rct_window* w, rct_widgetindex widgetIndex);
bool WidgetIsActiveTool(rct_window* w, rct_widgetindex widgetIndex);
void WidgetScrollGetPart(
rct_window* w, rct_widget* widget, const ScreenCoordsXY& screenCoords, ScreenCoordsXY& retScreenCoords,
rct_window* w, const rct_widget* widget, const ScreenCoordsXY& screenCoords, ScreenCoordsXY& retScreenCoords,
int32_t* output_scroll_area, int32_t* scroll_id);
void WidgetSetEnabled(rct_window* w, rct_widgetindex widgetIndex, bool enabled);

View File

@ -228,7 +228,7 @@ void window_close(rct_window* w)
g_window_list.erase(itWindow);
}
template<typename _TPred> static void window_close_by_condition(_TPred pred, uint32_t flags = WindowCloseFlags::None)
template<typename TPred> static void window_close_by_condition(TPred pred, uint32_t flags = WindowCloseFlags::None)
{
bool listUpdated;
do
@ -427,16 +427,16 @@ rct_widgetindex window_find_widget_from_point(rct_window* w, const ScreenCoordsX
rct_widgetindex widget_index = -1;
for (int32_t i = 0;; i++)
{
rct_widget* widget = &w->widgets[i];
if (widget->type == WindowWidgetType::Last)
const auto& widget = w->widgets[i];
if (widget.type == WindowWidgetType::Last)
{
break;
}
if (widget->type != WindowWidgetType::Empty && widget->IsVisible())
if (widget.type != WindowWidgetType::Empty && widget.IsVisible())
{
if (screenCoords.x >= w->windowPos.x + widget->left && screenCoords.x <= w->windowPos.x + widget->right
&& screenCoords.y >= w->windowPos.y + widget->top && screenCoords.y <= w->windowPos.y + widget->bottom)
if (screenCoords.x >= w->windowPos.x + widget.left && screenCoords.x <= w->windowPos.x + widget.right
&& screenCoords.y >= w->windowPos.y + widget.top && screenCoords.y <= w->windowPos.y + widget.bottom)
{
widget_index = i;
}
@ -445,8 +445,11 @@ rct_widgetindex window_find_widget_from_point(rct_window* w, const ScreenCoordsX
// Return next widget if a dropdown
if (widget_index != -1)
if (w->widgets[widget_index].type == WindowWidgetType::DropdownMenu)
{
const auto& widget = w->widgets[widget_index];
if (widget.type == WindowWidgetType::DropdownMenu)
widget_index++;
}
// Return the widget index
return widget_index;
@ -458,7 +461,7 @@ rct_widgetindex window_find_widget_from_point(rct_window* w, const ScreenCoordsX
*
* @param window The window to invalidate (esi).
*/
template<typename _TPred> static void window_invalidate_by_condition(_TPred pred)
template<typename TPred> static void window_invalidate_by_condition(TPred pred)
{
window_visit_each([pred](rct_window* w) {
if (pred(w))
@ -502,8 +505,6 @@ void window_invalidate_all()
*/
void widget_invalidate(rct_window* w, rct_widgetindex widgetIndex)
{
rct_widget* widget;
assert(w != nullptr);
#ifdef DEBUG
for (int32_t i = 0; i <= widgetIndex; i++)
@ -512,15 +513,15 @@ void widget_invalidate(rct_window* w, rct_widgetindex widgetIndex)
}
#endif
widget = &w->widgets[widgetIndex];
if (widget->left == -2)
const auto& widget = w->widgets[widgetIndex];
if (widget.left == -2)
return;
gfx_set_dirty_blocks({ { w->windowPos + ScreenCoordsXY{ widget->left, widget->top } },
{ w->windowPos + ScreenCoordsXY{ widget->right + 1, widget->bottom + 1 } } });
gfx_set_dirty_blocks({ { w->windowPos + ScreenCoordsXY{ widget.left, widget.top } },
{ w->windowPos + ScreenCoordsXY{ widget.right + 1, widget.bottom + 1 } } });
}
template<typename _TPred> static void widget_invalidate_by_condition(_TPred pred)
template<typename TPred> static void widget_invalidate_by_condition(TPred pred)
{
window_visit_each([pred](rct_window* w) {
if (pred(w))
@ -567,7 +568,6 @@ void window_update_scroll_widgets(rct_window* w)
{
int32_t scrollIndex, width, height, scrollPositionChanged;
rct_widgetindex widgetIndex;
rct_scroll* scroll;
rct_widget* widget;
widgetIndex = 0;
@ -578,32 +578,32 @@ void window_update_scroll_widgets(rct_window* w)
if (widget->type != WindowWidgetType::Scroll)
continue;
scroll = &w->scrolls[scrollIndex];
auto& scroll = w->scrolls[scrollIndex];
width = 0;
height = 0;
window_get_scroll_size(w, scrollIndex, &width, &height);
if (height == 0)
{
scroll->v_top = 0;
scroll.v_top = 0;
}
else if (width == 0)
{
scroll->h_left = 0;
scroll.h_left = 0;
}
width++;
height++;
scrollPositionChanged = 0;
if ((widget->content & SCROLL_HORIZONTAL) && width != scroll->h_right)
if ((widget->content & SCROLL_HORIZONTAL) && width != scroll.h_right)
{
scrollPositionChanged = 1;
scroll->h_right = width;
scroll.h_right = width;
}
if ((widget->content & SCROLL_VERTICAL) && height != scroll->v_bottom)
if ((widget->content & SCROLL_VERTICAL) && height != scroll.v_bottom)
{
scrollPositionChanged = 1;
scroll->v_bottom = height;
scroll.v_bottom = height;
}
if (scrollPositionChanged)
@ -623,7 +623,8 @@ int32_t window_get_scroll_data_index(rct_window* w, rct_widgetindex widget_index
assert(w != nullptr);
for (i = 0; i < widget_index; i++)
{
if (w->widgets[i].type == WindowWidgetType::Scroll)
const auto& widget = w->widgets[i];
if (widget.type == WindowWidgetType::Scroll)
result++;
}
return result;
@ -1290,8 +1291,9 @@ void window_resize(rct_window* w, int32_t dw, int32_t dh)
// Update scroll widgets
for (int32_t i = 0; i < 3; i++)
{
w->scrolls[i].h_right = WINDOW_SCROLL_UNDEFINED;
w->scrolls[i].v_bottom = WINDOW_SCROLL_UNDEFINED;
auto& scroll = w->scrolls[i];
scroll.h_right = WINDOW_SCROLL_UNDEFINED;
scroll.v_bottom = WINDOW_SCROLL_UNDEFINED;
}
window_update_scroll_widgets(w);
@ -1747,8 +1749,9 @@ void window_align_tabs(rct_window* w, rct_widgetindex start_tab_id, rct_widgetin
{
if (!(w->disabled_widgets & (1LL << i)))
{
w->widgets[i].left = x;
w->widgets[i].right = x + tab_width;
auto& widget = w->widgets[i];
widget.left = x;
widget.right = x + tab_width;
x += tab_width + 1;
}
}
@ -2179,64 +2182,64 @@ rct_windowclass window_get_classification(rct_window* window)
*/
void WidgetScrollUpdateThumbs(rct_window* w, rct_widgetindex widget_index)
{
rct_widget* widget = &w->widgets[widget_index];
rct_scroll* scroll = &w->scrolls[window_get_scroll_data_index(w, widget_index)];
const auto& widget = w->widgets[widget_index];
auto& scroll = w->scrolls[window_get_scroll_data_index(w, widget_index)];
if (scroll->flags & HSCROLLBAR_VISIBLE)
if (scroll.flags & HSCROLLBAR_VISIBLE)
{
int32_t view_size = widget->width() - 21;
if (scroll->flags & VSCROLLBAR_VISIBLE)
int32_t view_size = widget.width() - 21;
if (scroll.flags & VSCROLLBAR_VISIBLE)
view_size -= 11;
int32_t x = scroll->h_left * view_size;
if (scroll->h_right != 0)
x /= scroll->h_right;
scroll->h_thumb_left = x + 11;
int32_t x = scroll.h_left * view_size;
if (scroll.h_right != 0)
x /= scroll.h_right;
scroll.h_thumb_left = x + 11;
x = widget->width() - 2;
if (scroll->flags & VSCROLLBAR_VISIBLE)
x = widget.width() - 2;
if (scroll.flags & VSCROLLBAR_VISIBLE)
x -= 11;
x += scroll->h_left;
if (scroll->h_right != 0)
x = (x * view_size) / scroll->h_right;
x += scroll.h_left;
if (scroll.h_right != 0)
x = (x * view_size) / scroll.h_right;
x += 11;
view_size += 10;
scroll->h_thumb_right = std::min(x, view_size);
scroll.h_thumb_right = std::min(x, view_size);
if (scroll->h_thumb_right - scroll->h_thumb_left < 20)
if (scroll.h_thumb_right - scroll.h_thumb_left < 20)
{
double barPosition = (scroll->h_thumb_right * 1.0) / view_size;
double barPosition = (scroll.h_thumb_right * 1.0) / view_size;
scroll->h_thumb_left = static_cast<uint16_t>(std::lround(scroll->h_thumb_left - (20 * barPosition)));
scroll->h_thumb_right = static_cast<uint16_t>(std::lround(scroll->h_thumb_right + (20 * (1 - barPosition))));
scroll.h_thumb_left = static_cast<uint16_t>(std::lround(scroll.h_thumb_left - (20 * barPosition)));
scroll.h_thumb_right = static_cast<uint16_t>(std::lround(scroll.h_thumb_right + (20 * (1 - barPosition))));
}
}
if (scroll->flags & VSCROLLBAR_VISIBLE)
if (scroll.flags & VSCROLLBAR_VISIBLE)
{
int32_t view_size = widget->height() - 21;
if (scroll->flags & HSCROLLBAR_VISIBLE)
int32_t view_size = widget.height() - 21;
if (scroll.flags & HSCROLLBAR_VISIBLE)
view_size -= 11;
int32_t y = scroll->v_top * view_size;
if (scroll->v_bottom != 0)
y /= scroll->v_bottom;
scroll->v_thumb_top = y + 11;
int32_t y = scroll.v_top * view_size;
if (scroll.v_bottom != 0)
y /= scroll.v_bottom;
scroll.v_thumb_top = y + 11;
y = widget->height() - 2;
if (scroll->flags & HSCROLLBAR_VISIBLE)
y = widget.height() - 2;
if (scroll.flags & HSCROLLBAR_VISIBLE)
y -= 11;
y += scroll->v_top;
if (scroll->v_bottom != 0)
y = (y * view_size) / scroll->v_bottom;
y += scroll.v_top;
if (scroll.v_bottom != 0)
y = (y * view_size) / scroll.v_bottom;
y += 11;
view_size += 10;
scroll->v_thumb_bottom = std::min(y, view_size);
scroll.v_thumb_bottom = std::min(y, view_size);
if (scroll->v_thumb_bottom - scroll->v_thumb_top < 20)
if (scroll.v_thumb_bottom - scroll.v_thumb_top < 20)
{
double barPosition = (scroll->v_thumb_bottom * 1.0) / view_size;
double barPosition = (scroll.v_thumb_bottom * 1.0) / view_size;
scroll->v_thumb_top = static_cast<uint16_t>(std::lround(scroll->v_thumb_top - (20 * barPosition)));
scroll->v_thumb_bottom = static_cast<uint16_t>(std::lround(scroll->v_thumb_bottom + (20 * (1 - barPosition))));
scroll.v_thumb_top = static_cast<uint16_t>(std::lround(scroll.v_thumb_top - (20 * barPosition)));
scroll.v_thumb_bottom = static_cast<uint16_t>(std::lround(scroll.v_thumb_bottom + (20 * (1 - barPosition))));
}
}
}

View File

@ -597,28 +597,21 @@ void scenery_set_not_invented(const ScenerySelection& sceneryItem)
bool scenery_group_is_invented(int32_t sgIndex)
{
auto invented = false;
const auto sgEntry = get_scenery_group_entry(sgIndex);
if (sgEntry != nullptr && sgEntry->entry_count > 0)
if (sgEntry == nullptr || sgEntry->entry_count == 0)
{
if (gCheatsIgnoreResearchStatus)
{
invented = true;
}
else
{
for (auto i = 0; i < sgEntry->entry_count; i++)
{
auto sceneryEntry = sgEntry->scenery_entries[i];
if (scenery_is_invented(sceneryEntry))
{
invented = true;
break;
}
}
}
return false;
}
return invented;
if (gCheatsIgnoreResearchStatus)
{
return true;
}
return std::none_of(
std::begin(gResearchItemsUninvented), std::end(gResearchItemsUninvented), [sgIndex](const ResearchItem& item) {
return item.type == Research::EntryType::Scenery && item.entryIndex == sgIndex;
});
}
void scenery_group_set_invented(int32_t sgIndex)

View File

@ -42,7 +42,7 @@ void SmallSceneryObject::ReadLegacy(IReadObjectContext* context, OpenRCT2::IStre
rct_object_entry sgEntry = stream->ReadValue<rct_object_entry>();
SetPrimarySceneryGroup(ObjectEntryDescriptor(sgEntry));
if (scenery_small_entry_has_flag(&_legacyType, SMALL_SCENERY_FLAG_HAS_FRAME_OFFSETS))
if (_legacyType.HasFlag(SMALL_SCENERY_FLAG_HAS_FRAME_OFFSETS))
{
_frameOffsets = ReadFrameOffsets(stream);
}
@ -78,7 +78,7 @@ void SmallSceneryObject::Load()
_legacyType.scenery_tab_id = OBJECT_ENTRY_INDEX_NULL;
if (scenery_small_entry_has_flag(&_legacyType, SMALL_SCENERY_FLAG_HAS_FRAME_OFFSETS))
if (_legacyType.HasFlag(SMALL_SCENERY_FLAG_HAS_FRAME_OFFSETS))
{
_legacyType.frame_offsets = _frameOffsets.data();
}
@ -98,10 +98,10 @@ void SmallSceneryObject::Unload()
void SmallSceneryObject::DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const
{
uint32_t imageId = _legacyType.image;
if (scenery_small_entry_has_flag(&_legacyType, SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR))
if (_legacyType.HasFlag(SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR))
{
imageId |= 0x20D00000;
if (scenery_small_entry_has_flag(&_legacyType, SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR))
if (_legacyType.HasFlag(SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR))
{
imageId |= 0x92000000;
}
@ -110,28 +110,27 @@ void SmallSceneryObject::DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int3
auto screenCoords = ScreenCoordsXY{ width / 2, (height / 2) + (_legacyType.height / 2) };
screenCoords.y = std::min(screenCoords.y, height - 16);
if ((scenery_small_entry_has_flag(&_legacyType, SMALL_SCENERY_FLAG_FULL_TILE))
&& (scenery_small_entry_has_flag(&_legacyType, SMALL_SCENERY_FLAG_VOFFSET_CENTRE)))
if ((_legacyType.HasFlag(SMALL_SCENERY_FLAG_FULL_TILE)) && (_legacyType.HasFlag(SMALL_SCENERY_FLAG_VOFFSET_CENTRE)))
{
screenCoords.y -= 12;
}
gfx_draw_sprite(dpi, imageId, screenCoords, 0);
if (scenery_small_entry_has_flag(&_legacyType, SMALL_SCENERY_FLAG_HAS_GLASS))
if (_legacyType.HasFlag(SMALL_SCENERY_FLAG_HAS_GLASS))
{
imageId = _legacyType.image + 0x44500004;
if (scenery_small_entry_has_flag(&_legacyType, SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR))
if (_legacyType.HasFlag(SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR))
{
imageId |= 0x92000000;
}
gfx_draw_sprite(dpi, imageId, screenCoords, 0);
}
if (scenery_small_entry_has_flag(&_legacyType, SMALL_SCENERY_FLAG_ANIMATED_FG))
if (_legacyType.HasFlag(SMALL_SCENERY_FLAG_ANIMATED_FG))
{
imageId = _legacyType.image + 4;
if (scenery_small_entry_has_flag(&_legacyType, SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR))
if (_legacyType.HasFlag(SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR))
{
imageId |= 0x92000000;
}

View File

@ -312,7 +312,7 @@ namespace PaintSortFlags
static constexpr uint8_t OutsideQuadrant = (1U << 7);
} // namespace PaintSortFlags
template<uint8_t _TRotation>
template<uint8_t TRotation>
static paint_struct* PaintArrangeStructsHelperRotation(paint_struct* ps_next, uint16_t quadrantIndex, uint8_t flag)
{
paint_struct* ps;
@ -403,7 +403,7 @@ static paint_struct* PaintArrangeStructsHelperRotation(paint_struct* ps_next, ui
const paint_struct_bound_box& currentBBox = ps_next->bounds;
const bool compareResult = CheckBoundingBox<_TRotation>(initialBBox, currentBBox);
const bool compareResult = CheckBoundingBox<TRotation>(initialBBox, currentBBox);
if (compareResult)
{

View File

@ -75,9 +75,9 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
boxlength.y = 2;
int8_t x_offset = 0;
int8_t y_offset = 0;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE))
{
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_HALF_SPACE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_HALF_SPACE))
{
// 6DFFE3:
static constexpr const CoordsXY scenery_half_tile_offsets[] = {
@ -97,13 +97,13 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
{
x_offset = 15;
y_offset = 15;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
{
x_offset = 3;
y_offset = 3;
boxlength.x = 26;
boxlength.y = 26;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_NO_WALLS))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_NO_WALLS))
{
x_offset = 1;
y_offset = 1;
@ -130,7 +130,7 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
{
boxlength.z = 128;
}
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_CAN_WITHER))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_CAN_WITHER))
{
if (sceneryElement.GetAge() >= SCENERY_WITHER_AGE_THRESHOLD_1)
{
@ -141,9 +141,9 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
baseImageid += 4;
}
}
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR))
{
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR))
{
baseImageid |= SPRITE_ID_PALETTE_COLOUR_2(sceneryElement.GetPrimaryColour(), sceneryElement.GetSecondaryColour());
}
@ -156,13 +156,13 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
{
baseImageid = (baseImageid & 0x7FFFF) | marker;
}
if (!(scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_VISIBLE_WHEN_ZOOMED)))
if (!(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_VISIBLE_WHEN_ZOOMED)))
{
PaintAddImageAsParent(
session, baseImageid, { x_offset, y_offset, height }, { boxlength.x, boxlength.y, boxlength.z - 1 }, boxoffset);
}
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_HAS_GLASS))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_HAS_GLASS))
{
if (marker == 0)
{
@ -176,13 +176,13 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
}
}
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_ANIMATED))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_ANIMATED))
{
rct_drawpixelinfo* dpi = &session->DPI;
if ((scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_VISIBLE_WHEN_ZOOMED)) || (dpi->zoom_level <= 1))
if ((sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_VISIBLE_WHEN_ZOOMED)) || (dpi->zoom_level <= 1))
{
// 6E01A9:
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FOUNTAIN_SPRAY_1))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FOUNTAIN_SPRAY_1))
{
// 6E0512:
int32_t image_id = ((gCurrentTicks / 2) & 0xF) + sceneryEntry->image + 4;
@ -194,7 +194,7 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
session, image_id, x_offset, y_offset, boxlength.x, boxlength.y, boxlength.z - 1, height, boxoffset.x,
boxoffset.y, boxoffset.z);
}
else if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FOUNTAIN_SPRAY_4))
else if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FOUNTAIN_SPRAY_4))
{
// 6E043B:
int32_t image_id = ((gCurrentTicks / 2) & 0xF) + sceneryEntry->image + 8;
@ -224,7 +224,7 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
session, image_id, x_offset, y_offset, boxlength.x, boxlength.y, boxlength.z - 1, height, boxoffset.x,
boxoffset.y, boxoffset.z);
}
else if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_IS_CLOCK))
else if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_IS_CLOCK))
{
// 6E035C:
int32_t minuteImageOffset = ((gRealTimeOfDay.minute + 6) * 17) / 256;
@ -267,7 +267,7 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
session, image_id, x_offset, y_offset, boxlength.x, boxlength.y, boxlength.z - 1, height, boxoffset.x,
boxoffset.y, boxoffset.z);
}
else if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_SWAMP_GOO))
else if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_SWAMP_GOO))
{
// 6E02F6:
int32_t image_id = gCurrentTicks;
@ -283,10 +283,10 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
session, image_id, x_offset, y_offset, boxlength.x, boxlength.y, boxlength.z - 1, height, boxoffset.x,
boxoffset.y, boxoffset.z);
}
else if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_HAS_FRAME_OFFSETS))
else if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_HAS_FRAME_OFFSETS))
{
int32_t frame = gCurrentTicks;
if (!(scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_COG)))
if (!(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_COG)))
{
// 6E01F8:
frame += ((session->SpritePosition.x / 4) + (session->SpritePosition.y / 4));
@ -302,13 +302,13 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
image_id = sceneryEntry->frame_offsets[frame];
}
image_id = (image_id * 4) + direction + sceneryEntry->image;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_VISIBLE_WHEN_ZOOMED | SMALL_SCENERY_FLAG17))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_VISIBLE_WHEN_ZOOMED | SMALL_SCENERY_FLAG17))
{
image_id += 4;
}
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR))
{
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR))
{
image_id |= SPRITE_ID_PALETTE_COLOUR_2(
sceneryElement.GetPrimaryColour(), sceneryElement.GetSecondaryColour());
@ -322,7 +322,7 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
{
image_id = (image_id & 0x7FFFF) | marker;
}
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_VISIBLE_WHEN_ZOOMED))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_VISIBLE_WHEN_ZOOMED))
{
PaintAddImageAsParent(
session, image_id, { x_offset, y_offset, height }, { boxlength.x, boxlength.y, boxlength.z - 1 },
@ -340,7 +340,7 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
// 6E0556: Draw supports:
if (sceneryElement.NeedsSupports())
{
if (!(scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_NO_SUPPORTS)))
if (!(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_NO_SUPPORTS)))
{
int32_t ax = 0;
int32_t supportHeight = height;
@ -350,7 +350,7 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
ax = 49;
}
uint32_t supportImageColourFlags = IMAGE_TYPE_REMAP;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_PAINT_SUPPORTS))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_PAINT_SUPPORTS))
{
supportImageColourFlags = SPRITE_ID_PALETTE_COLOUR_1(sceneryElement.GetPrimaryColour());
}
@ -373,19 +373,19 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
paint_util_set_general_support_height(session, ceil2(height, 8), 0x20);
// 6E05FF:
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_BUILD_DIRECTLY_ONTOP))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_BUILD_DIRECTLY_ONTOP))
{
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE))
{
// 6E0825:
paint_util_set_segment_support_height(session, SEGMENT_C4, height, 0x20);
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
{
paint_util_set_segment_support_height(session, SEGMENTS_ALL & ~SEGMENT_C4, height, 0x20);
}
return;
}
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
{
// 6E075C:
direction = (sceneryElement.GetSceneryQuadrant() + rotation) % 4;
@ -395,16 +395,16 @@ void PaintSmallScenery(paint_session* session, uint8_t direction, int32_t height
}
return;
}
if (scenery_small_entry_has_flag(sceneryEntry, (SMALL_SCENERY_FLAG27 | SMALL_SCENERY_FLAG_FULL_TILE)))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG27 | SMALL_SCENERY_FLAG_FULL_TILE))
{
paint_util_set_segment_support_height(session, SEGMENT_C4, 0xFFFF, 0);
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
{
paint_util_set_segment_support_height(session, SEGMENTS_ALL & ~SEGMENT_C4, 0xFFFF, 0);
}
return;
}
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
{
direction = (sceneryElement.GetSceneryQuadrant() + rotation) % 4;
paint_util_set_segment_support_height(

View File

@ -112,12 +112,13 @@ bool staff_hire_new_member(StaffType staffType, EntertainerCostume entertainerTy
}
auto hireStaffAction = StaffHireNewAction(autoPosition, staffType, entertainerType, staffOrders);
hireStaffAction.SetCallback([=](const GameAction*, const StaffHireNewActionResult* res) -> void {
hireStaffAction.SetCallback([=](const GameAction*, const GameActions::Result* res) -> void {
if (res->Error != GameActions::Status::Ok)
return;
auto actionResult = res->GetData<StaffHireNewActionResult>();
// Open window for new staff.
auto* staff = GetEntity<Staff>(res->peepSriteIndex);
auto* staff = GetEntity<Staff>(actionResult.StaffEntityId);
auto intent = Intent(WC_PEEP);
intent.putExtra(INTENT_EXTRA_PEEP, staff);
context_open_intent(&intent);
@ -1265,7 +1266,7 @@ void Staff::UpdateWatering()
auto* sceneryEntry = tile_element->AsSmallScenery()->GetEntry();
if (!scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_CAN_BE_WATERED))
if (!sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_CAN_BE_WATERED))
continue;
tile_element->AsSmallScenery()->SetAge(0);
@ -1652,7 +1653,7 @@ bool Staff::UpdatePatrollingFindWatering()
auto* sceneryEntry = tile_element->AsSmallScenery()->GetEntry();
if (sceneryEntry == nullptr || !scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_CAN_BE_WATERED))
if (sceneryEntry == nullptr || !sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_CAN_BE_WATERED))
{
continue;
}

View File

@ -308,9 +308,9 @@ static bool OnCrash(
static std::wstring GetDumpDirectory()
{
auto env = GetContext()->GetPlatformEnvironment();
auto crashPath = env->GetDirectoryPath(DIRBASE::OPENRCT2, DIRID::CRASH);
auto crashPath = env->GetDirectoryPath(DIRBASE::USER, DIRID::CRASH);
auto result = String::ToWideChar(crashPath.c_str());
auto result = String::ToWideChar(crashPath);
return result;
}

View File

@ -215,15 +215,20 @@ public:
gScenarioCategory = static_cast<SCENARIO_CATEGORY>(_s6.info.category);
// Some scenarios have their scenario details in UTF-8, due to earlier bugs in OpenRCT2.
if (!IsLikelyUTF8(_s6.info.name) && !IsLikelyUTF8(_s6.info.details))
auto loadMaybeUTF8 = [](std::string_view str) -> std::string {
return !IsLikelyUTF8(str) ? rct2_to_utf8(str, RCT2LanguageId::EnglishUK) : std::string(str);
};
if (_s6.header.type == S6_TYPE_SCENARIO)
{
gScenarioName = rct2_to_utf8(_s6.info.name, RCT2LanguageId::EnglishUK);
gScenarioDetails = rct2_to_utf8(_s6.info.details, RCT2LanguageId::EnglishUK);
gScenarioName = loadMaybeUTF8(_s6.info.name);
gScenarioDetails = loadMaybeUTF8(_s6.info.details);
}
else
{
gScenarioName = _s6.info.name;
gScenarioDetails = _s6.info.details;
// Saved games do not have an info chunk
gScenarioName = loadMaybeUTF8(_s6.scenario_name);
gScenarioDetails = loadMaybeUTF8(_s6.scenario_description);
}
gDateMonthsElapsed = static_cast<int32_t>(_s6.elapsed_months);

View File

@ -823,10 +823,10 @@ static void track_design_mirror_scenery(TrackDesign* td6)
auto* sceneryEntry = reinterpret_cast<const SmallSceneryEntry*>(obj->GetLegacyData());
scenery.y = -scenery.y;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_DIAGONAL))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_DIAGONAL))
{
scenery.flags ^= (1 << 0);
if (!scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE))
if (!sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE))
{
scenery.flags ^= (1 << 2);
}
@ -989,10 +989,8 @@ static bool TrackDesignPlaceSceneryElementRemoveGhost(
quadrant &= 3;
auto* sceneryEntry = get_small_scenery_entry(entryInfo->Index);
if (!(!scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE)
&& scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_DIAGONAL))
&& scenery_small_entry_has_flag(
sceneryEntry,
if (!(!sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE) && sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_DIAGONAL))
&& sceneryEntry->HasFlag(
SMALL_SCENERY_FLAG_DIAGONAL | SMALL_SCENERY_FLAG_HALF_SPACE | SMALL_SCENERY_FLAG_THREE_QUARTERS))
{
quadrant = 0;
@ -1921,8 +1919,7 @@ static money32 track_design_ride_create_command(int32_t type, int32_t subType, i
auto gameAction = RideCreateAction(type, subType, 0, 0);
gameAction.SetFlags(flags);
auto r = GameActions::ExecuteNested(&gameAction);
const RideCreateGameActionResult* res = static_cast<RideCreateGameActionResult*>(r.get());
auto res = GameActions::ExecuteNested(&gameAction);
// Callee's of this function expect MONEY32_UNDEFINED in case of failure.
if (res->Error != GameActions::Status::Ok)
@ -1930,7 +1927,7 @@ static money32 track_design_ride_create_command(int32_t type, int32_t subType, i
return MONEY32_UNDEFINED;
}
*outRideIndex = res->rideIndex;
*outRideIndex = res->GetData<ride_id_t>();
return res->Cost;
}

View File

@ -1928,7 +1928,7 @@ void Vehicle::UpdateMeasurements()
if (sceneryEntry == nullptr)
continue;
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE))
{
coverFound = true;
break;

View File

@ -884,18 +884,21 @@ DukValue ScriptEngine::GameActionResultToDuk(const GameAction& action, const std
if (action.GetType() == GameCommand::CreateRide)
{
auto& rideCreateResult = static_cast<RideCreateGameActionResult&>(*result.get());
if (rideCreateResult.rideIndex != RIDE_ID_NULL)
if (result->Error == GameActions::Status::Ok)
{
obj.Set("ride", EnumValue(rideCreateResult.rideIndex));
const auto rideIndex = result->GetData<ride_id_t>();
obj.Set("ride", EnumValue(rideIndex));
}
}
else if (action.GetType() == GameCommand::HireNewStaffMember)
{
auto& staffHireResult = static_cast<StaffHireNewActionResult&>(*result.get());
if (staffHireResult.peepSriteIndex != SPRITE_INDEX_NULL)
if (result->Error == GameActions::Status::Ok)
{
obj.Set("peep", staffHireResult.peepSriteIndex);
const auto actionResult = result->GetData<StaffHireNewActionResult>();
if (actionResult.StaffEntityId != SPRITE_INDEX_NULL)
{
obj.Set("peep", actionResult.StaffEntityId);
}
}
}

View File

@ -2226,7 +2226,7 @@ bool map_surface_is_blocked(const CoordsXY& mapCoords)
{
return false;
}
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE))
return true;
}
return false;

View File

@ -177,16 +177,15 @@ static bool map_animation_invalidate_small_scenery(const CoordsXYZ& loc)
if (sceneryEntry == nullptr)
continue;
if (scenery_small_entry_has_flag(
sceneryEntry,
if (sceneryEntry->HasFlag(
SMALL_SCENERY_FLAG_FOUNTAIN_SPRAY_1 | SMALL_SCENERY_FLAG_FOUNTAIN_SPRAY_4 | SMALL_SCENERY_FLAG_SWAMP_GOO
| SMALL_SCENERY_FLAG_HAS_FRAME_OFFSETS))
| SMALL_SCENERY_FLAG_HAS_FRAME_OFFSETS))
{
map_invalidate_tile_zoom1({ loc, loc.z, tileElement->GetClearanceZ() });
return false;
}
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_IS_CLOCK))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_IS_CLOCK))
{
// Peep, looking at scenery
if (!(gCurrentTicks & 0x3FF) && game_is_not_paused())
@ -638,7 +637,7 @@ void AutoCreateMapAnimations()
{
auto sceneryEl = el->AsSmallScenery();
auto* sceneryEntry = sceneryEl->GetEntry();
if (sceneryEntry != nullptr && scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_ANIMATED))
if (sceneryEntry != nullptr && sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_ANIMATED))
{
map_animation_create(MAP_ANIMATION_TYPE_SMALL_SCENERY, loc);
}

View File

@ -112,13 +112,12 @@ void SmallSceneryElement::UpdateAge(const CoordsXY& sceneryPos)
return;
}
if (gCheatsDisablePlantAging && (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_CAN_BE_WATERED)))
if (gCheatsDisablePlantAging && sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_CAN_BE_WATERED))
{
return;
}
if (!scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_CAN_BE_WATERED) || WeatherIsDry(gClimateCurrent.Weather)
|| GetAge() < 5)
if (!sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_CAN_BE_WATERED) || WeatherIsDry(gClimateCurrent.Weather) || GetAge() < 5)
{
IncreaseAge(sceneryPos);
return;
@ -146,7 +145,7 @@ void SmallSceneryElement::UpdateAge(const CoordsXY& sceneryPos)
return;
case TILE_ELEMENT_TYPE_SMALL_SCENERY:
sceneryEntry = tileElementAbove->AsSmallScenery()->GetEntry();
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
{
IncreaseAge(sceneryPos);
return;

View File

@ -131,6 +131,11 @@ struct SmallSceneryEntry : SceneryEntryBase
uint16_t animation_mask;
uint16_t num_frames;
ObjectEntryIndex scenery_tab_id;
constexpr bool HasFlag(const uint32_t _flags) const
{
return (flags & _flags) != 0;
}
};
struct WallSceneryEntry : SceneryEntryBase

View File

@ -37,7 +37,7 @@ static int32_t map_place_clear_func(
if (gParkFlags & PARK_FLAGS_FORBID_TREE_REMOVAL)
{
if (scenery != nullptr && scenery_small_entry_has_flag(scenery, SMALL_SCENERY_FLAG_IS_TREE))
if (scenery != nullptr && scenery->HasFlag(SMALL_SCENERY_FLAG_IS_TREE))
return 1;
}
@ -76,11 +76,6 @@ int32_t map_place_non_scenery_clear_func(TileElement** tile_element, const Coord
return map_place_clear_func(tile_element, coords, flags, price, /*is_scenery=*/false);
}
bool scenery_small_entry_has_flag(const SmallSceneryEntry* sceneryEntry, uint32_t flags)
{
return static_cast<bool>(sceneryEntry->flags & flags);
}
uint8_t SmallSceneryElement::GetSceneryQuadrant() const
{
return (this->type & TILE_ELEMENT_QUADRANT_MASK) >> 6;
@ -126,7 +121,7 @@ void SmallSceneryElement::IncreaseAge(const CoordsXY& sceneryPos)
{
auto* sceneryEntry = GetEntry();
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_CAN_WITHER))
if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_CAN_WITHER))
{
map_invalidate_tile_zoom1({ sceneryPos, GetBaseZ(), GetClearanceZ() });
}

View File

@ -13,7 +13,7 @@
#include "Map.h"
#include "Scenery.h"
enum SMALL_SCENERY_FLAGS
enum SMALL_SCENERY_FLAGS : uint32_t
{
SMALL_SCENERY_FLAG_FULL_TILE = (1 << 0), // 0x1
SMALL_SCENERY_FLAG_VOFFSET_CENTRE = (1 << 1), // 0x2
@ -53,5 +53,4 @@ enum
MAP_ELEM_SMALL_SCENERY_COLOUR_FLAG_NEEDS_SUPPORTS = (1 << 5),
};
bool scenery_small_entry_has_flag(const SmallSceneryEntry* sceneryEntry, uint32_t flags);
SmallSceneryEntry* get_small_scenery_entry(ObjectEntryIndex entryIndex);