mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge remote-tracking branch 'upstream/develop' into new-save-format
This commit is contained in:
commit
b96565266c
|
@ -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
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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 #
|
||||
##############
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
||||
|
|
|
@ -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>();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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() });
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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{};
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() });
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue