mirror of
https://github.com/OpenRCT2/OpenRCT2.git
synced 2025-01-22 10:21:57 -05:00
Co-authored-by: Tulio Leao <tupaschoal@gmail.com>
This commit is contained in:
parent
bb53ba10f6
commit
0a28f6b0b9
2 changed files with 595 additions and 657 deletions
|
@ -106,6 +106,7 @@ The following people are not part of the development team, but have been contrib
|
|||
* Josh Trzebiatowski (trzejos) - Ride and scenery filtering
|
||||
* (kyphii) - Extended color selection
|
||||
* Phumdol Lookthipnapha (beam41) - Misc.
|
||||
* Wenzhao Qiu (qwzhaox) - Misc.
|
||||
|
||||
## Bug fixes
|
||||
* (KirilAngelov)
|
||||
|
|
|
@ -69,72 +69,347 @@ static Widget window_game_bottom_toolbar_widgets[] =
|
|||
|
||||
uint8_t gToolbarDirtyFlags;
|
||||
|
||||
static void WindowGameBottomToolbarMouseup(WindowBase *w, WidgetIndex widgetIndex);
|
||||
static OpenRCT2String WindowGameBottomToolbarTooltip(WindowBase* w, const WidgetIndex widgetIndex, const StringId fallback);
|
||||
static void WindowGameBottomToolbarInvalidate(WindowBase *w);
|
||||
static void WindowGameBottomToolbarPaint(WindowBase *w, DrawPixelInfo& dpi);
|
||||
static void WindowGameBottomToolbarUpdate(WindowBase* w);
|
||||
static void WindowGameBottomToolbarCursor(WindowBase *w, WidgetIndex widgetIndex, const ScreenCoordsXY& screenCoords, CursorID *cursorId);
|
||||
static void WindowGameBottomToolbarUnknown05(WindowBase *w);
|
||||
|
||||
static void WindowGameBottomToolbarDrawLeftPanel(DrawPixelInfo& dpi, WindowBase *w);
|
||||
static void WindowGameBottomToolbarDrawParkRating(DrawPixelInfo& dpi, WindowBase *w, int32_t colour, const ScreenCoordsXY& coords, uint8_t factor);
|
||||
static void WindowGameBottomToolbarDrawRightPanel(DrawPixelInfo& dpi, WindowBase *w);
|
||||
static void WindowGameBottomToolbarDrawNewsItem(DrawPixelInfo& dpi, WindowBase *w);
|
||||
static void WindowGameBottomToolbarDrawMiddlePanel(DrawPixelInfo& dpi, WindowBase *w);
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0097BFDC
|
||||
*/
|
||||
static WindowEventList window_game_bottom_toolbar_events([](auto& events)
|
||||
class GameBottomToolbar final : public Window
|
||||
{
|
||||
events.mouse_up = &WindowGameBottomToolbarMouseup;
|
||||
events.unknown_05 = &WindowGameBottomToolbarUnknown05;
|
||||
events.update = &WindowGameBottomToolbarUpdate;
|
||||
events.tooltip = &WindowGameBottomToolbarTooltip;
|
||||
events.cursor = &WindowGameBottomToolbarCursor;
|
||||
events.invalidate = &WindowGameBottomToolbarInvalidate;
|
||||
events.paint = &WindowGameBottomToolbarPaint;
|
||||
});
|
||||
// clang-format on
|
||||
private:
|
||||
|
||||
static void WindowGameBottomToolbarInvalidateDirtyWidgets(WindowBase* w);
|
||||
|
||||
/**
|
||||
* Creates the main game bottom toolbar window.
|
||||
* rct2: 0x0066B52F (part of 0x0066B3E8)
|
||||
*/
|
||||
WindowBase* WindowGameBottomToolbarOpen()
|
||||
void DrawLeftPanel(DrawPixelInfo &dpi)
|
||||
{
|
||||
int32_t screenWidth = ContextGetWidth();
|
||||
int32_t screenHeight = ContextGetHeight();
|
||||
const auto topLeft = windowPos
|
||||
+ ScreenCoordsXY{ window_game_bottom_toolbar_widgets[WIDX_LEFT_OUTSET].left + 1,
|
||||
window_game_bottom_toolbar_widgets[WIDX_LEFT_OUTSET].top + 1 };
|
||||
const auto bottomRight = windowPos
|
||||
+ ScreenCoordsXY{ window_game_bottom_toolbar_widgets[WIDX_LEFT_OUTSET].right - 1,
|
||||
window_game_bottom_toolbar_widgets[WIDX_LEFT_OUTSET].bottom - 1 };
|
||||
// Draw green inset rectangle on panel
|
||||
GfxFillRectInset(dpi, { topLeft, bottomRight }, colours[1], INSET_RECT_F_30);
|
||||
|
||||
// Figure out how much line height we have to work with.
|
||||
uint32_t line_height = FontGetLineHeight(FontStyle::Medium);
|
||||
uint32_t toolbar_height = line_height * 2 + 12;
|
||||
|
||||
WindowBase* window = WindowCreate(
|
||||
ScreenCoordsXY(0, screenHeight - toolbar_height), screenWidth, toolbar_height, &window_game_bottom_toolbar_events,
|
||||
WindowClass::BottomToolbar, WF_STICK_TO_FRONT | WF_TRANSPARENT | WF_NO_BACKGROUND);
|
||||
window->widgets = window_game_bottom_toolbar_widgets;
|
||||
// Draw money
|
||||
if (!(gParkFlags & PARK_FLAGS_NO_MONEY))
|
||||
{
|
||||
Widget widget = window_game_bottom_toolbar_widgets[WIDX_MONEY];
|
||||
auto screenCoords = ScreenCoordsXY{ windowPos.x + widget.midX(),
|
||||
windowPos.y + widget.midY() - (line_height == 10 ? 5 : 6) };
|
||||
|
||||
window->frame_no = 0;
|
||||
WindowInitScrollWidgets(*window);
|
||||
colour_t colour
|
||||
= (gHoverWidget.window_classification == WindowClass::BottomToolbar && gHoverWidget.widget_index == WIDX_MONEY
|
||||
? COLOUR_WHITE
|
||||
: NOT_TRANSLUCENT(colours[0]));
|
||||
StringId stringId = gCash < 0 ? STR_BOTTOM_TOOLBAR_CASH_NEGATIVE : STR_BOTTOM_TOOLBAR_CASH;
|
||||
auto ft = Formatter();
|
||||
ft.Add<money64>(gCash);
|
||||
DrawTextBasic(dpi, screenCoords, stringId, ft, { colour, TextAlignment::CENTRE });
|
||||
}
|
||||
|
||||
static constexpr const StringId _guestCountFormats[] = {
|
||||
STR_BOTTOM_TOOLBAR_NUM_GUESTS_STABLE,
|
||||
STR_BOTTOM_TOOLBAR_NUM_GUESTS_DECREASE,
|
||||
STR_BOTTOM_TOOLBAR_NUM_GUESTS_INCREASE,
|
||||
};
|
||||
|
||||
static constexpr const StringId _guestCountFormatsSingular[] = {
|
||||
STR_BOTTOM_TOOLBAR_NUM_GUESTS_STABLE_SINGULAR,
|
||||
STR_BOTTOM_TOOLBAR_NUM_GUESTS_DECREASE_SINGULAR,
|
||||
STR_BOTTOM_TOOLBAR_NUM_GUESTS_INCREASE_SINGULAR,
|
||||
};
|
||||
|
||||
// Draw guests
|
||||
{
|
||||
Widget widget = window_game_bottom_toolbar_widgets[WIDX_GUESTS];
|
||||
auto screenCoords = ScreenCoordsXY{ windowPos.x + widget.midX(), windowPos.y + widget.midY() - 6 };
|
||||
|
||||
StringId stringId = gNumGuestsInPark == 1 ? _guestCountFormatsSingular[gGuestChangeModifier]
|
||||
: _guestCountFormats[gGuestChangeModifier];
|
||||
colour_t colour
|
||||
= (gHoverWidget.window_classification == WindowClass::BottomToolbar && gHoverWidget.widget_index == WIDX_GUESTS
|
||||
? COLOUR_WHITE
|
||||
: NOT_TRANSLUCENT(colours[0]));
|
||||
auto ft = Formatter();
|
||||
ft.Add<uint32_t>(gNumGuestsInPark);
|
||||
DrawTextBasic(dpi, screenCoords, stringId, ft, { colour, TextAlignment::CENTRE });
|
||||
}
|
||||
|
||||
// Draw park rating
|
||||
{
|
||||
Widget widget = window_game_bottom_toolbar_widgets[WIDX_PARK_RATING];
|
||||
auto screenCoords = windowPos + ScreenCoordsXY{ widget.left + 11, widget.midY() - 5 };
|
||||
|
||||
DrawParkRating(
|
||||
dpi, colours[3], screenCoords, std::max(10, ((gParkRating / 4) * 263) / 256));
|
||||
}
|
||||
}
|
||||
|
||||
void DrawParkRating(DrawPixelInfo &dpi, int32_t colour, const ScreenCoordsXY& coords, uint8_t factor)
|
||||
{
|
||||
int16_t bar_width = (factor * 114) / 255;
|
||||
GfxFillRectInset(
|
||||
dpi, { coords + ScreenCoordsXY{ 1, 1 }, coords + ScreenCoordsXY{ 114, 9 } }, colours[1], INSET_RECT_F_30);
|
||||
if (!(colour & BAR_BLINK) || GameIsPaused() || (gCurrentRealTimeTicks & 8))
|
||||
{
|
||||
if (bar_width > 2)
|
||||
{
|
||||
GfxFillRectInset(dpi, { coords + ScreenCoordsXY{ 2, 2 }, coords + ScreenCoordsXY{ bar_width - 1, 8 } }, colour, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw thumbs on the sides
|
||||
GfxDrawSprite(dpi, ImageId(SPR_RATING_LOW), coords - ScreenCoordsXY{ 14, 0 });
|
||||
GfxDrawSprite(dpi, ImageId(SPR_RATING_HIGH), coords + ScreenCoordsXY{ 114, 0 });
|
||||
}
|
||||
|
||||
void DrawRightPanel(DrawPixelInfo &dpi)
|
||||
{
|
||||
const auto topLeft = windowPos
|
||||
+ ScreenCoordsXY{ window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].left + 1,
|
||||
window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].top + 1 };
|
||||
const auto bottomRight = windowPos
|
||||
+ ScreenCoordsXY{ window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].right - 1,
|
||||
window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].bottom - 1 };
|
||||
// Draw green inset rectangle on panel
|
||||
GfxFillRectInset(dpi, { topLeft, bottomRight }, colours[1], INSET_RECT_F_30);
|
||||
|
||||
auto screenCoords = ScreenCoordsXY{ (window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].left
|
||||
+ window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].right)
|
||||
/ 2
|
||||
+ windowPos.x,
|
||||
window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].top + windowPos.y + 2 };
|
||||
|
||||
// Date
|
||||
auto& date = GetDate();
|
||||
int32_t year = date.GetYear() + 1;
|
||||
int32_t month = date.GetMonth();
|
||||
int32_t day = date.GetDay();
|
||||
|
||||
colour_t colour
|
||||
= (gHoverWidget.window_classification == WindowClass::BottomToolbar && gHoverWidget.widget_index == WIDX_DATE
|
||||
? COLOUR_WHITE
|
||||
: NOT_TRANSLUCENT(colours[0]));
|
||||
StringId stringId = DateFormatStringFormatIds[gConfigGeneral.DateFormat];
|
||||
auto ft = Formatter();
|
||||
ft.Add<StringId>(DateDayNames[day]);
|
||||
ft.Add<int16_t>(month);
|
||||
ft.Add<int16_t>(year);
|
||||
DrawTextBasic(dpi, screenCoords, stringId, ft, { colour, TextAlignment::CENTRE });
|
||||
|
||||
// Figure out how much line height we have to work with.
|
||||
uint32_t line_height = FontGetLineHeight(FontStyle::Medium);
|
||||
|
||||
// Temperature
|
||||
screenCoords = { windowPos.x + window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].left + 15,
|
||||
static_cast<int32_t>(screenCoords.y + line_height + 1) };
|
||||
|
||||
int32_t temperature = gClimateCurrent.Temperature;
|
||||
StringId format = STR_CELSIUS_VALUE;
|
||||
if (gConfigGeneral.TemperatureFormat == TemperatureUnit::Fahrenheit)
|
||||
{
|
||||
temperature = ClimateCelsiusToFahrenheit(temperature);
|
||||
format = STR_FAHRENHEIT_VALUE;
|
||||
}
|
||||
ft = Formatter();
|
||||
ft.Add<int16_t>(temperature);
|
||||
DrawTextBasic(dpi, screenCoords + ScreenCoordsXY{ 0, 6 }, format, ft);
|
||||
screenCoords.x += 30;
|
||||
|
||||
// Current weather
|
||||
auto currentWeatherSpriteId = ClimateGetWeatherSpriteId(gClimateCurrent);
|
||||
GfxDrawSprite(dpi, ImageId(currentWeatherSpriteId), screenCoords);
|
||||
|
||||
// Next weather
|
||||
auto nextWeatherSpriteId = ClimateGetWeatherSpriteId(gClimateNext);
|
||||
if (currentWeatherSpriteId != nextWeatherSpriteId)
|
||||
{
|
||||
if (gClimateUpdateTimer < 960)
|
||||
{
|
||||
GfxDrawSprite(dpi, ImageId(SPR_NEXT_WEATHER), screenCoords + ScreenCoordsXY{ 27, 5 });
|
||||
GfxDrawSprite(dpi, ImageId(nextWeatherSpriteId), screenCoords + ScreenCoordsXY{ 40, 0 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawNewsItem(DrawPixelInfo &dpi)
|
||||
{
|
||||
auto* middleOutsetWidget = &window_game_bottom_toolbar_widgets[WIDX_MIDDLE_OUTSET];
|
||||
auto* newsItem = News::GetItem(0);
|
||||
|
||||
// Current news item
|
||||
GfxFillRectInset(
|
||||
dpi,
|
||||
|
||||
{ windowPos + ScreenCoordsXY{ middleOutsetWidget->left + 1, middleOutsetWidget->top + 1 },
|
||||
windowPos + ScreenCoordsXY{ middleOutsetWidget->right - 1, middleOutsetWidget->bottom - 1 } },
|
||||
colours[2], INSET_RECT_F_30);
|
||||
|
||||
// Text
|
||||
auto screenCoords = windowPos + ScreenCoordsXY{ middleOutsetWidget->midX(), middleOutsetWidget->top + 11 };
|
||||
int32_t itemWidth = middleOutsetWidget->width() - 62;
|
||||
DrawNewsTicker(
|
||||
dpi, screenCoords, itemWidth, COLOUR_BRIGHT_GREEN, STR_BOTTOM_TOOLBAR_NEWS_TEXT, newsItem->Text, newsItem->Ticks);
|
||||
|
||||
screenCoords = windowPos
|
||||
+ ScreenCoordsXY{ window_game_bottom_toolbar_widgets[WIDX_NEWS_SUBJECT].left,
|
||||
window_game_bottom_toolbar_widgets[WIDX_NEWS_SUBJECT].top };
|
||||
switch (newsItem->Type)
|
||||
{
|
||||
case News::ItemType::Ride:
|
||||
GfxDrawSprite(dpi, ImageId(SPR_RIDE), screenCoords);
|
||||
break;
|
||||
case News::ItemType::PeepOnRide:
|
||||
case News::ItemType::Peep:
|
||||
{
|
||||
if (newsItem->HasButton())
|
||||
break;
|
||||
|
||||
DrawPixelInfo cliped_dpi;
|
||||
if (!ClipDrawPixelInfo(cliped_dpi, dpi, screenCoords + ScreenCoordsXY{ 1, 1 }, 22, 22))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
auto peep = TryGetEntity<Peep>(EntityId::FromUnderlying(newsItem->Assoc));
|
||||
if (peep == nullptr)
|
||||
return;
|
||||
|
||||
auto clipCoords = ScreenCoordsXY{ 10, 19 };
|
||||
auto* staff = peep->As<Staff>();
|
||||
if (staff != nullptr && staff->AssignedStaffType == StaffType::Entertainer)
|
||||
{
|
||||
clipCoords.y += 3;
|
||||
}
|
||||
|
||||
uint32_t image_id_base = GetPeepAnimation(peep->SpriteType).base_image;
|
||||
image_id_base += frame_no & 0xFFFFFFFC;
|
||||
image_id_base++;
|
||||
|
||||
auto image_id = ImageId(image_id_base, peep->TshirtColour, peep->TrousersColour);
|
||||
GfxDrawSprite(cliped_dpi, image_id, clipCoords);
|
||||
|
||||
auto* guest = peep->As<Guest>();
|
||||
if (guest != nullptr)
|
||||
{
|
||||
if (image_id_base >= 0x2A1D && image_id_base < 0x2A3D)
|
||||
{
|
||||
GfxDrawSprite(cliped_dpi, ImageId(image_id_base + 32, guest->BalloonColour), clipCoords);
|
||||
}
|
||||
else if (image_id_base >= 0x2BBD && image_id_base < 0x2BDD)
|
||||
{
|
||||
GfxDrawSprite(cliped_dpi, ImageId(image_id_base + 32, guest->UmbrellaColour), clipCoords);
|
||||
}
|
||||
else if (image_id_base >= 0x29DD && image_id_base < 0x29FD)
|
||||
{
|
||||
GfxDrawSprite(cliped_dpi, ImageId(image_id_base + 32, guest->HatColour), clipCoords);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case News::ItemType::Money:
|
||||
case News::ItemType::Campaign:
|
||||
GfxDrawSprite(dpi, ImageId(SPR_FINANCE), screenCoords);
|
||||
break;
|
||||
case News::ItemType::Research:
|
||||
GfxDrawSprite(dpi, ImageId(newsItem->Assoc < 0x10000 ? SPR_NEW_SCENERY : SPR_NEW_RIDE), screenCoords);
|
||||
break;
|
||||
case News::ItemType::Peeps:
|
||||
GfxDrawSprite(dpi, ImageId(SPR_GUESTS), screenCoords);
|
||||
break;
|
||||
case News::ItemType::Award:
|
||||
GfxDrawSprite(dpi, ImageId(SPR_AWARD), screenCoords);
|
||||
break;
|
||||
case News::ItemType::Graph:
|
||||
GfxDrawSprite(dpi, ImageId(SPR_GRAPH), screenCoords);
|
||||
break;
|
||||
case News::ItemType::Null:
|
||||
case News::ItemType::Blank:
|
||||
case News::ItemType::Count:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawMiddlePanel(DrawPixelInfo &dpi)
|
||||
{
|
||||
Widget* middleOutsetWidget = &window_game_bottom_toolbar_widgets[WIDX_MIDDLE_OUTSET];
|
||||
|
||||
GfxFillRectInset(
|
||||
dpi,
|
||||
{ windowPos + ScreenCoordsXY{ middleOutsetWidget->left + 1, middleOutsetWidget->top + 1 },
|
||||
windowPos + ScreenCoordsXY{ middleOutsetWidget->right - 1, middleOutsetWidget->bottom - 1 } },
|
||||
colours[1], INSET_RECT_F_30);
|
||||
|
||||
// Figure out how much line height we have to work with.
|
||||
uint32_t line_height = FontGetLineHeight(FontStyle::Medium);
|
||||
|
||||
ScreenCoordsXY middleWidgetCoords(
|
||||
windowPos.x + middleOutsetWidget->midX(), windowPos.y + middleOutsetWidget->top + line_height + 1);
|
||||
int32_t panelWidth = middleOutsetWidget->width() - 62;
|
||||
|
||||
// Check if there is a map tooltip to draw
|
||||
StringId stringId;
|
||||
auto ft = GetMapTooltip();
|
||||
std::memcpy(&stringId, ft.Data(), sizeof(StringId));
|
||||
if (stringId == STR_NONE)
|
||||
{
|
||||
DrawTextWrapped(
|
||||
dpi, middleWidgetCoords, panelWidth, STR_TITLE_SEQUENCE_OPENRCT2, ft, { colours[0], TextAlignment::CENTRE });
|
||||
}
|
||||
else
|
||||
{
|
||||
// Show tooltip in bottom toolbar
|
||||
DrawTextWrapped(dpi, middleWidgetCoords, panelWidth, STR_STRINGID, ft, { colours[0], TextAlignment::CENTRE });
|
||||
}
|
||||
}
|
||||
|
||||
void InvalidateDirtyWidgets()
|
||||
{
|
||||
if (gToolbarDirtyFlags & BTM_TB_DIRTY_FLAG_MONEY)
|
||||
{
|
||||
gToolbarDirtyFlags &= ~BTM_TB_DIRTY_FLAG_MONEY;
|
||||
InvalidateWidget(WIDX_LEFT_INSET);
|
||||
}
|
||||
|
||||
if (gToolbarDirtyFlags & BTM_TB_DIRTY_FLAG_DATE)
|
||||
{
|
||||
gToolbarDirtyFlags &= ~BTM_TB_DIRTY_FLAG_DATE;
|
||||
InvalidateWidget(WIDX_RIGHT_INSET);
|
||||
}
|
||||
|
||||
if (gToolbarDirtyFlags & BTM_TB_DIRTY_FLAG_PEEP_COUNT)
|
||||
{
|
||||
gToolbarDirtyFlags &= ~BTM_TB_DIRTY_FLAG_PEEP_COUNT;
|
||||
InvalidateWidget(WIDX_LEFT_INSET);
|
||||
}
|
||||
|
||||
if (gToolbarDirtyFlags & BTM_TB_DIRTY_FLAG_CLIMATE)
|
||||
{
|
||||
gToolbarDirtyFlags &= ~BTM_TB_DIRTY_FLAG_CLIMATE;
|
||||
InvalidateWidget(WIDX_RIGHT_INSET);
|
||||
}
|
||||
|
||||
if (gToolbarDirtyFlags & BTM_TB_DIRTY_FLAG_PARK_RATING)
|
||||
{
|
||||
gToolbarDirtyFlags &= ~BTM_TB_DIRTY_FLAG_PARK_RATING;
|
||||
InvalidateWidget(WIDX_LEFT_INSET);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
GameBottomToolbar()
|
||||
{
|
||||
widgets = window_game_bottom_toolbar_widgets;
|
||||
|
||||
frame_no = 0;
|
||||
InitScrollWidgets();
|
||||
|
||||
// Reset the middle widget to not show by default.
|
||||
// If it is required to be shown news_update will reshow it.
|
||||
window_game_bottom_toolbar_widgets[WIDX_MIDDLE_OUTSET].type = WindowWidgetType::Empty;
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066C588
|
||||
*/
|
||||
static void WindowGameBottomToolbarMouseup(WindowBase* w, WidgetIndex widgetIndex)
|
||||
void OnMouseUp(WidgetIndex widgetIndex) override
|
||||
{
|
||||
|
||||
News::Item* newsItem;
|
||||
|
||||
switch (widgetIndex)
|
||||
|
@ -188,7 +463,7 @@ static void WindowGameBottomToolbarMouseup(WindowBase* w, WidgetIndex widgetInde
|
|||
}
|
||||
}
|
||||
|
||||
static OpenRCT2String WindowGameBottomToolbarTooltip(WindowBase* w, const WidgetIndex widgetIndex, const StringId fallback)
|
||||
OpenRCT2String OnTooltip(WidgetIndex widgetIndex, StringId fallback) override
|
||||
{
|
||||
auto ft = Formatter();
|
||||
|
||||
|
@ -205,50 +480,46 @@ static OpenRCT2String WindowGameBottomToolbarTooltip(WindowBase* w, const Widget
|
|||
return { fallback, ft };
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066BBA0
|
||||
*/
|
||||
static void WindowGameBottomToolbarInvalidate(WindowBase* w)
|
||||
void OnPrepareDraw() override
|
||||
{
|
||||
// Figure out how much line height we have to work with.
|
||||
uint32_t line_height = FontGetLineHeight(FontStyle::Medium);
|
||||
|
||||
// Reset dimensions as appropriate -- in case we're switching languages.
|
||||
w->height = line_height * 2 + 12;
|
||||
w->windowPos.y = ContextGetHeight() - w->height;
|
||||
height = line_height * 2 + 12;
|
||||
windowPos.y = ContextGetHeight() - height;
|
||||
|
||||
// Change height of widgets in accordance with line height.
|
||||
w->widgets[WIDX_LEFT_OUTSET].bottom = w->widgets[WIDX_MIDDLE_OUTSET].bottom = w->widgets[WIDX_RIGHT_OUTSET].bottom
|
||||
widgets[WIDX_LEFT_OUTSET].bottom = widgets[WIDX_MIDDLE_OUTSET].bottom = widgets[WIDX_RIGHT_OUTSET].bottom
|
||||
= line_height * 3 + 3;
|
||||
w->widgets[WIDX_LEFT_INSET].bottom = w->widgets[WIDX_MIDDLE_INSET].bottom = w->widgets[WIDX_RIGHT_INSET].bottom
|
||||
widgets[WIDX_LEFT_INSET].bottom = widgets[WIDX_MIDDLE_INSET].bottom = widgets[WIDX_RIGHT_INSET].bottom
|
||||
= line_height * 3 + 1;
|
||||
|
||||
// Reposition left widgets in accordance with line height... depending on whether there is money in play.
|
||||
if (gParkFlags & PARK_FLAGS_NO_MONEY)
|
||||
{
|
||||
w->widgets[WIDX_MONEY].type = WindowWidgetType::Empty;
|
||||
w->widgets[WIDX_GUESTS].top = 1;
|
||||
w->widgets[WIDX_GUESTS].bottom = line_height + 7;
|
||||
w->widgets[WIDX_PARK_RATING].top = line_height + 8;
|
||||
w->widgets[WIDX_PARK_RATING].bottom = w->height - 1;
|
||||
widgets[WIDX_MONEY].type = WindowWidgetType::Empty;
|
||||
widgets[WIDX_GUESTS].top = 1;
|
||||
widgets[WIDX_GUESTS].bottom = line_height + 7;
|
||||
widgets[WIDX_PARK_RATING].top = line_height + 8;
|
||||
widgets[WIDX_PARK_RATING].bottom = height - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
w->widgets[WIDX_MONEY].type = WindowWidgetType::FlatBtn;
|
||||
w->widgets[WIDX_MONEY].bottom = w->widgets[WIDX_MONEY].top + line_height;
|
||||
w->widgets[WIDX_GUESTS].top = w->widgets[WIDX_MONEY].bottom + 1;
|
||||
w->widgets[WIDX_GUESTS].bottom = w->widgets[WIDX_GUESTS].top + line_height;
|
||||
w->widgets[WIDX_PARK_RATING].top = w->widgets[WIDX_GUESTS].bottom - 1;
|
||||
w->widgets[WIDX_PARK_RATING].bottom = w->height - 1;
|
||||
widgets[WIDX_MONEY].type = WindowWidgetType::FlatBtn;
|
||||
widgets[WIDX_MONEY].bottom = widgets[WIDX_MONEY].top + line_height;
|
||||
widgets[WIDX_GUESTS].top = widgets[WIDX_MONEY].bottom + 1;
|
||||
widgets[WIDX_GUESTS].bottom = widgets[WIDX_GUESTS].top + line_height;
|
||||
widgets[WIDX_PARK_RATING].top = widgets[WIDX_GUESTS].bottom - 1;
|
||||
widgets[WIDX_PARK_RATING].bottom = height - 1;
|
||||
}
|
||||
|
||||
// Reposition right widgets in accordance with line height, too.
|
||||
w->widgets[WIDX_DATE].bottom = line_height + 1;
|
||||
widgets[WIDX_DATE].bottom = line_height + 1;
|
||||
|
||||
// Anchor the middle and right panel to the right
|
||||
int32_t x = ContextGetWidth();
|
||||
w->width = x;
|
||||
width = x;
|
||||
x--;
|
||||
window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].right = x;
|
||||
x -= 2;
|
||||
|
@ -299,403 +570,77 @@ static void WindowGameBottomToolbarInvalidate(WindowBase* w)
|
|||
window_game_bottom_toolbar_widgets[WIDX_NEWS_LOCATE].type = WindowWidgetType::FlatBtn;
|
||||
window_game_bottom_toolbar_widgets[WIDX_MIDDLE_OUTSET].colour = 2;
|
||||
window_game_bottom_toolbar_widgets[WIDX_MIDDLE_INSET].colour = 2;
|
||||
w->disabled_widgets &= ~(1uLL << WIDX_NEWS_SUBJECT);
|
||||
w->disabled_widgets &= ~(1uLL << WIDX_NEWS_LOCATE);
|
||||
disabled_widgets &= ~(1uLL << WIDX_NEWS_SUBJECT);
|
||||
disabled_widgets &= ~(1uLL << WIDX_NEWS_LOCATE);
|
||||
|
||||
// Find out if the news item is no longer valid
|
||||
auto subjectLoc = News::GetSubjectLocation(newsItem->Type, newsItem->Assoc);
|
||||
|
||||
if (!subjectLoc.has_value())
|
||||
w->disabled_widgets |= (1uLL << WIDX_NEWS_LOCATE);
|
||||
disabled_widgets |= (1uLL << WIDX_NEWS_LOCATE);
|
||||
|
||||
if (!(newsItem->TypeHasSubject()))
|
||||
{
|
||||
w->disabled_widgets |= (1uLL << WIDX_NEWS_SUBJECT);
|
||||
disabled_widgets |= (1uLL << WIDX_NEWS_SUBJECT);
|
||||
window_game_bottom_toolbar_widgets[WIDX_NEWS_SUBJECT].type = WindowWidgetType::Empty;
|
||||
}
|
||||
|
||||
if (newsItem->HasButton())
|
||||
{
|
||||
w->disabled_widgets |= (1uLL << WIDX_NEWS_SUBJECT);
|
||||
w->disabled_widgets |= (1uLL << WIDX_NEWS_LOCATE);
|
||||
disabled_widgets |= (1uLL << WIDX_NEWS_SUBJECT);
|
||||
disabled_widgets |= (1uLL << WIDX_NEWS_LOCATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066BB79
|
||||
*/
|
||||
void WindowGameBottomToolbarInvalidateNewsItem()
|
||||
{
|
||||
if (gScreenFlags == SCREEN_FLAGS_PLAYING)
|
||||
{
|
||||
WidgetInvalidateByClass(WindowClass::BottomToolbar, WIDX_MIDDLE_OUTSET);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066BC87
|
||||
*/
|
||||
static void WindowGameBottomToolbarPaint(WindowBase* w, DrawPixelInfo& dpi)
|
||||
void OnDraw(DrawPixelInfo &dpi) override
|
||||
{
|
||||
auto leftWidget = window_game_bottom_toolbar_widgets[WIDX_LEFT_OUTSET];
|
||||
auto rightWidget = window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET];
|
||||
auto middleWidget = window_game_bottom_toolbar_widgets[WIDX_MIDDLE_OUTSET];
|
||||
|
||||
// Draw panel grey backgrounds
|
||||
auto leftTop = w->windowPos + ScreenCoordsXY{ leftWidget.left, leftWidget.top };
|
||||
auto rightBottom = w->windowPos + ScreenCoordsXY{ leftWidget.right, leftWidget.bottom };
|
||||
auto leftTop = windowPos + ScreenCoordsXY{ leftWidget.left, leftWidget.top };
|
||||
auto rightBottom = windowPos + ScreenCoordsXY{ leftWidget.right, leftWidget.bottom };
|
||||
GfxFilterRect(dpi, { leftTop, rightBottom }, FilterPaletteID::Palette51);
|
||||
|
||||
leftTop = w->windowPos + ScreenCoordsXY{ rightWidget.left, rightWidget.top };
|
||||
rightBottom = w->windowPos + ScreenCoordsXY{ rightWidget.right, rightWidget.bottom };
|
||||
leftTop = windowPos + ScreenCoordsXY{ rightWidget.left, rightWidget.top };
|
||||
rightBottom = windowPos + ScreenCoordsXY{ rightWidget.right, rightWidget.bottom };
|
||||
GfxFilterRect(dpi, { leftTop, rightBottom }, FilterPaletteID::Palette51);
|
||||
|
||||
if (ThemeGetFlags() & UITHEME_FLAG_USE_FULL_BOTTOM_TOOLBAR)
|
||||
{
|
||||
// Draw grey background
|
||||
leftTop = w->windowPos + ScreenCoordsXY{ middleWidget.left, middleWidget.top };
|
||||
rightBottom = w->windowPos + ScreenCoordsXY{ middleWidget.right, middleWidget.bottom };
|
||||
leftTop = windowPos + ScreenCoordsXY{ middleWidget.left, middleWidget.top };
|
||||
rightBottom = windowPos + ScreenCoordsXY{ middleWidget.right, middleWidget.bottom };
|
||||
GfxFilterRect(dpi, { leftTop, rightBottom }, FilterPaletteID::Palette51);
|
||||
}
|
||||
|
||||
WindowDrawWidgets(*w, dpi);
|
||||
DrawWidgets(dpi);
|
||||
|
||||
WindowGameBottomToolbarDrawLeftPanel(dpi, w);
|
||||
WindowGameBottomToolbarDrawRightPanel(dpi, w);
|
||||
DrawLeftPanel(dpi);
|
||||
DrawRightPanel(dpi);
|
||||
|
||||
if (!News::IsQueueEmpty())
|
||||
{
|
||||
WindowGameBottomToolbarDrawNewsItem(dpi, w);
|
||||
DrawNewsItem(dpi);
|
||||
}
|
||||
else if (ThemeGetFlags() & UITHEME_FLAG_USE_FULL_BOTTOM_TOOLBAR)
|
||||
{
|
||||
WindowGameBottomToolbarDrawMiddlePanel(dpi, w);
|
||||
DrawMiddlePanel(dpi);
|
||||
}
|
||||
}
|
||||
|
||||
static void WindowGameBottomToolbarDrawLeftPanel(DrawPixelInfo& dpi, WindowBase* w)
|
||||
void OnUpdate() override
|
||||
{
|
||||
const auto topLeft = w->windowPos
|
||||
+ ScreenCoordsXY{ window_game_bottom_toolbar_widgets[WIDX_LEFT_OUTSET].left + 1,
|
||||
window_game_bottom_toolbar_widgets[WIDX_LEFT_OUTSET].top + 1 };
|
||||
const auto bottomRight = w->windowPos
|
||||
+ ScreenCoordsXY{ window_game_bottom_toolbar_widgets[WIDX_LEFT_OUTSET].right - 1,
|
||||
window_game_bottom_toolbar_widgets[WIDX_LEFT_OUTSET].bottom - 1 };
|
||||
// Draw green inset rectangle on panel
|
||||
GfxFillRectInset(dpi, { topLeft, bottomRight }, w->colours[1], INSET_RECT_F_30);
|
||||
frame_no++;
|
||||
if (frame_no >= 24)
|
||||
frame_no = 0;
|
||||
|
||||
// Figure out how much line height we have to work with.
|
||||
uint32_t line_height = FontGetLineHeight(FontStyle::Medium);
|
||||
|
||||
// Draw money
|
||||
if (!(gParkFlags & PARK_FLAGS_NO_MONEY))
|
||||
{
|
||||
Widget widget = window_game_bottom_toolbar_widgets[WIDX_MONEY];
|
||||
auto screenCoords = ScreenCoordsXY{ w->windowPos.x + widget.midX(),
|
||||
w->windowPos.y + widget.midY() - (line_height == 10 ? 5 : 6) };
|
||||
|
||||
colour_t colour
|
||||
= (gHoverWidget.window_classification == WindowClass::BottomToolbar && gHoverWidget.widget_index == WIDX_MONEY
|
||||
? COLOUR_WHITE
|
||||
: NOT_TRANSLUCENT(w->colours[0]));
|
||||
StringId stringId = gCash < 0 ? STR_BOTTOM_TOOLBAR_CASH_NEGATIVE : STR_BOTTOM_TOOLBAR_CASH;
|
||||
auto ft = Formatter();
|
||||
ft.Add<money64>(gCash);
|
||||
DrawTextBasic(dpi, screenCoords, stringId, ft, { colour, TextAlignment::CENTRE });
|
||||
InvalidateDirtyWidgets();
|
||||
}
|
||||
|
||||
static constexpr const StringId _guestCountFormats[] = {
|
||||
STR_BOTTOM_TOOLBAR_NUM_GUESTS_STABLE,
|
||||
STR_BOTTOM_TOOLBAR_NUM_GUESTS_DECREASE,
|
||||
STR_BOTTOM_TOOLBAR_NUM_GUESTS_INCREASE,
|
||||
};
|
||||
|
||||
static constexpr const StringId _guestCountFormatsSingular[] = {
|
||||
STR_BOTTOM_TOOLBAR_NUM_GUESTS_STABLE_SINGULAR,
|
||||
STR_BOTTOM_TOOLBAR_NUM_GUESTS_DECREASE_SINGULAR,
|
||||
STR_BOTTOM_TOOLBAR_NUM_GUESTS_INCREASE_SINGULAR,
|
||||
};
|
||||
|
||||
// Draw guests
|
||||
{
|
||||
Widget widget = window_game_bottom_toolbar_widgets[WIDX_GUESTS];
|
||||
auto screenCoords = ScreenCoordsXY{ w->windowPos.x + widget.midX(), w->windowPos.y + widget.midY() - 6 };
|
||||
|
||||
StringId stringId = gNumGuestsInPark == 1 ? _guestCountFormatsSingular[gGuestChangeModifier]
|
||||
: _guestCountFormats[gGuestChangeModifier];
|
||||
colour_t colour
|
||||
= (gHoverWidget.window_classification == WindowClass::BottomToolbar && gHoverWidget.widget_index == WIDX_GUESTS
|
||||
? COLOUR_WHITE
|
||||
: NOT_TRANSLUCENT(w->colours[0]));
|
||||
auto ft = Formatter();
|
||||
ft.Add<uint32_t>(gNumGuestsInPark);
|
||||
DrawTextBasic(dpi, screenCoords, stringId, ft, { colour, TextAlignment::CENTRE });
|
||||
}
|
||||
|
||||
// Draw park rating
|
||||
{
|
||||
Widget widget = window_game_bottom_toolbar_widgets[WIDX_PARK_RATING];
|
||||
auto screenCoords = w->windowPos + ScreenCoordsXY{ widget.left + 11, widget.midY() - 5 };
|
||||
|
||||
WindowGameBottomToolbarDrawParkRating(
|
||||
dpi, w, w->colours[3], screenCoords, std::max(10, ((gParkRating / 4) * 263) / 256));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066C76C
|
||||
*/
|
||||
static void WindowGameBottomToolbarDrawParkRating(
|
||||
DrawPixelInfo& dpi, WindowBase* w, int32_t colour, const ScreenCoordsXY& coords, uint8_t factor)
|
||||
{
|
||||
int16_t bar_width;
|
||||
|
||||
bar_width = (factor * 114) / 255;
|
||||
GfxFillRectInset(
|
||||
dpi, { coords + ScreenCoordsXY{ 1, 1 }, coords + ScreenCoordsXY{ 114, 9 } }, w->colours[1], INSET_RECT_F_30);
|
||||
if (!(colour & BAR_BLINK) || GameIsPaused() || (gCurrentRealTimeTicks & 8))
|
||||
{
|
||||
if (bar_width > 2)
|
||||
{
|
||||
GfxFillRectInset(dpi, { coords + ScreenCoordsXY{ 2, 2 }, coords + ScreenCoordsXY{ bar_width - 1, 8 } }, colour, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw thumbs on the sides
|
||||
GfxDrawSprite(dpi, ImageId(SPR_RATING_LOW), coords - ScreenCoordsXY{ 14, 0 });
|
||||
GfxDrawSprite(dpi, ImageId(SPR_RATING_HIGH), coords + ScreenCoordsXY{ 114, 0 });
|
||||
}
|
||||
|
||||
static void WindowGameBottomToolbarDrawRightPanel(DrawPixelInfo& dpi, WindowBase* w)
|
||||
{
|
||||
const auto topLeft = w->windowPos
|
||||
+ ScreenCoordsXY{ window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].left + 1,
|
||||
window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].top + 1 };
|
||||
const auto bottomRight = w->windowPos
|
||||
+ ScreenCoordsXY{ window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].right - 1,
|
||||
window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].bottom - 1 };
|
||||
// Draw green inset rectangle on panel
|
||||
GfxFillRectInset(dpi, { topLeft, bottomRight }, w->colours[1], INSET_RECT_F_30);
|
||||
|
||||
auto screenCoords = ScreenCoordsXY{ (window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].left
|
||||
+ window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].right)
|
||||
/ 2
|
||||
+ w->windowPos.x,
|
||||
window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].top + w->windowPos.y + 2 };
|
||||
|
||||
// Date
|
||||
auto& date = GetDate();
|
||||
int32_t year = date.GetYear() + 1;
|
||||
int32_t month = date.GetMonth();
|
||||
int32_t day = date.GetDay();
|
||||
|
||||
colour_t colour
|
||||
= (gHoverWidget.window_classification == WindowClass::BottomToolbar && gHoverWidget.widget_index == WIDX_DATE
|
||||
? COLOUR_WHITE
|
||||
: NOT_TRANSLUCENT(w->colours[0]));
|
||||
StringId stringId = DateFormatStringFormatIds[gConfigGeneral.DateFormat];
|
||||
auto ft = Formatter();
|
||||
ft.Add<StringId>(DateDayNames[day]);
|
||||
ft.Add<int16_t>(month);
|
||||
ft.Add<int16_t>(year);
|
||||
DrawTextBasic(dpi, screenCoords, stringId, ft, { colour, TextAlignment::CENTRE });
|
||||
|
||||
// Figure out how much line height we have to work with.
|
||||
uint32_t line_height = FontGetLineHeight(FontStyle::Medium);
|
||||
|
||||
// Temperature
|
||||
screenCoords = { w->windowPos.x + window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].left + 15,
|
||||
static_cast<int32_t>(screenCoords.y + line_height + 1) };
|
||||
|
||||
int32_t temperature = gClimateCurrent.Temperature;
|
||||
StringId format = STR_CELSIUS_VALUE;
|
||||
if (gConfigGeneral.TemperatureFormat == TemperatureUnit::Fahrenheit)
|
||||
{
|
||||
temperature = ClimateCelsiusToFahrenheit(temperature);
|
||||
format = STR_FAHRENHEIT_VALUE;
|
||||
}
|
||||
ft = Formatter();
|
||||
ft.Add<int16_t>(temperature);
|
||||
DrawTextBasic(dpi, screenCoords + ScreenCoordsXY{ 0, 6 }, format, ft);
|
||||
screenCoords.x += 30;
|
||||
|
||||
// Current weather
|
||||
auto currentWeatherSpriteId = ClimateGetWeatherSpriteId(gClimateCurrent);
|
||||
GfxDrawSprite(dpi, ImageId(currentWeatherSpriteId), screenCoords);
|
||||
|
||||
// Next weather
|
||||
auto nextWeatherSpriteId = ClimateGetWeatherSpriteId(gClimateNext);
|
||||
if (currentWeatherSpriteId != nextWeatherSpriteId)
|
||||
{
|
||||
if (gClimateUpdateTimer < 960)
|
||||
{
|
||||
GfxDrawSprite(dpi, ImageId(SPR_NEXT_WEATHER), screenCoords + ScreenCoordsXY{ 27, 5 });
|
||||
GfxDrawSprite(dpi, ImageId(nextWeatherSpriteId), screenCoords + ScreenCoordsXY{ 40, 0 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066BFA5
|
||||
*/
|
||||
static void WindowGameBottomToolbarDrawNewsItem(DrawPixelInfo& dpi, WindowBase* w)
|
||||
{
|
||||
int32_t width;
|
||||
News::Item* newsItem;
|
||||
Widget* middleOutsetWidget;
|
||||
|
||||
middleOutsetWidget = &window_game_bottom_toolbar_widgets[WIDX_MIDDLE_OUTSET];
|
||||
newsItem = News::GetItem(0);
|
||||
|
||||
// Current news item
|
||||
GfxFillRectInset(
|
||||
dpi,
|
||||
{ w->windowPos + ScreenCoordsXY{ middleOutsetWidget->left + 1, middleOutsetWidget->top + 1 },
|
||||
w->windowPos + ScreenCoordsXY{ middleOutsetWidget->right - 1, middleOutsetWidget->bottom - 1 } },
|
||||
w->colours[2], INSET_RECT_F_30);
|
||||
|
||||
// Text
|
||||
auto screenCoords = w->windowPos + ScreenCoordsXY{ middleOutsetWidget->midX(), middleOutsetWidget->top + 11 };
|
||||
width = middleOutsetWidget->width() - 62;
|
||||
DrawNewsTicker(
|
||||
dpi, screenCoords, width, COLOUR_BRIGHT_GREEN, STR_BOTTOM_TOOLBAR_NEWS_TEXT, newsItem->Text, newsItem->Ticks);
|
||||
|
||||
screenCoords = w->windowPos
|
||||
+ ScreenCoordsXY{ window_game_bottom_toolbar_widgets[WIDX_NEWS_SUBJECT].left,
|
||||
window_game_bottom_toolbar_widgets[WIDX_NEWS_SUBJECT].top };
|
||||
switch (newsItem->Type)
|
||||
{
|
||||
case News::ItemType::Ride:
|
||||
GfxDrawSprite(dpi, ImageId(SPR_RIDE), screenCoords);
|
||||
break;
|
||||
case News::ItemType::PeepOnRide:
|
||||
case News::ItemType::Peep:
|
||||
{
|
||||
if (newsItem->HasButton())
|
||||
break;
|
||||
|
||||
DrawPixelInfo cliped_dpi;
|
||||
if (!ClipDrawPixelInfo(cliped_dpi, dpi, screenCoords + ScreenCoordsXY{ 1, 1 }, 22, 22))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
auto peep = TryGetEntity<Peep>(EntityId::FromUnderlying(newsItem->Assoc));
|
||||
if (peep == nullptr)
|
||||
return;
|
||||
|
||||
auto clipCoords = ScreenCoordsXY{ 10, 19 };
|
||||
auto* staff = peep->As<Staff>();
|
||||
if (staff != nullptr && staff->AssignedStaffType == StaffType::Entertainer)
|
||||
{
|
||||
clipCoords.y += 3;
|
||||
}
|
||||
|
||||
uint32_t image_id_base = GetPeepAnimation(peep->SpriteType).base_image;
|
||||
image_id_base += w->frame_no & 0xFFFFFFFC;
|
||||
image_id_base++;
|
||||
|
||||
auto image_id = ImageId(image_id_base, peep->TshirtColour, peep->TrousersColour);
|
||||
GfxDrawSprite(cliped_dpi, image_id, clipCoords);
|
||||
|
||||
auto* guest = peep->As<Guest>();
|
||||
if (guest != nullptr)
|
||||
{
|
||||
if (image_id_base >= 0x2A1D && image_id_base < 0x2A3D)
|
||||
{
|
||||
GfxDrawSprite(cliped_dpi, ImageId(image_id_base + 32, guest->BalloonColour), clipCoords);
|
||||
}
|
||||
else if (image_id_base >= 0x2BBD && image_id_base < 0x2BDD)
|
||||
{
|
||||
GfxDrawSprite(cliped_dpi, ImageId(image_id_base + 32, guest->UmbrellaColour), clipCoords);
|
||||
}
|
||||
else if (image_id_base >= 0x29DD && image_id_base < 0x29FD)
|
||||
{
|
||||
GfxDrawSprite(cliped_dpi, ImageId(image_id_base + 32, guest->HatColour), clipCoords);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case News::ItemType::Money:
|
||||
case News::ItemType::Campaign:
|
||||
GfxDrawSprite(dpi, ImageId(SPR_FINANCE), screenCoords);
|
||||
break;
|
||||
case News::ItemType::Research:
|
||||
GfxDrawSprite(dpi, ImageId(newsItem->Assoc < 0x10000 ? SPR_NEW_SCENERY : SPR_NEW_RIDE), screenCoords);
|
||||
break;
|
||||
case News::ItemType::Peeps:
|
||||
GfxDrawSprite(dpi, ImageId(SPR_GUESTS), screenCoords);
|
||||
break;
|
||||
case News::ItemType::Award:
|
||||
GfxDrawSprite(dpi, ImageId(SPR_AWARD), screenCoords);
|
||||
break;
|
||||
case News::ItemType::Graph:
|
||||
GfxDrawSprite(dpi, ImageId(SPR_GRAPH), screenCoords);
|
||||
break;
|
||||
case News::ItemType::Null:
|
||||
case News::ItemType::Blank:
|
||||
case News::ItemType::Count:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void WindowGameBottomToolbarDrawMiddlePanel(DrawPixelInfo& dpi, WindowBase* w)
|
||||
{
|
||||
Widget* middleOutsetWidget = &window_game_bottom_toolbar_widgets[WIDX_MIDDLE_OUTSET];
|
||||
|
||||
GfxFillRectInset(
|
||||
dpi,
|
||||
{ w->windowPos + ScreenCoordsXY{ middleOutsetWidget->left + 1, middleOutsetWidget->top + 1 },
|
||||
w->windowPos + ScreenCoordsXY{ middleOutsetWidget->right - 1, middleOutsetWidget->bottom - 1 } },
|
||||
w->colours[1], INSET_RECT_F_30);
|
||||
|
||||
// Figure out how much line height we have to work with.
|
||||
uint32_t line_height = FontGetLineHeight(FontStyle::Medium);
|
||||
|
||||
ScreenCoordsXY middleWidgetCoords(
|
||||
w->windowPos.x + middleOutsetWidget->midX(), w->windowPos.y + middleOutsetWidget->top + line_height + 1);
|
||||
int32_t width = middleOutsetWidget->width() - 62;
|
||||
|
||||
// Check if there is a map tooltip to draw
|
||||
StringId stringId;
|
||||
auto ft = GetMapTooltip();
|
||||
std::memcpy(&stringId, ft.Data(), sizeof(StringId));
|
||||
if (stringId == STR_NONE)
|
||||
{
|
||||
DrawTextWrapped(
|
||||
dpi, middleWidgetCoords, width, STR_TITLE_SEQUENCE_OPENRCT2, ft, { w->colours[0], TextAlignment::CENTRE });
|
||||
}
|
||||
else
|
||||
{
|
||||
// Show tooltip in bottom toolbar
|
||||
DrawTextWrapped(dpi, middleWidgetCoords, width, STR_STRINGID, ft, { w->colours[0], TextAlignment::CENTRE });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066C6D8
|
||||
*/
|
||||
static void WindowGameBottomToolbarUpdate(WindowBase* w)
|
||||
{
|
||||
w->frame_no++;
|
||||
if (w->frame_no >= 24)
|
||||
w->frame_no = 0;
|
||||
|
||||
WindowGameBottomToolbarInvalidateDirtyWidgets(w);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066C644
|
||||
*/
|
||||
static void WindowGameBottomToolbarCursor(
|
||||
WindowBase* w, WidgetIndex widgetIndex, const ScreenCoordsXY& screenCoords, CursorID* cursorId)
|
||||
CursorID OnCursor(WidgetIndex widgetIndex, const ScreenCoordsXY& screenCoords, CursorID cursorId) override
|
||||
{
|
||||
switch (widgetIndex)
|
||||
{
|
||||
|
@ -706,50 +651,42 @@ static void WindowGameBottomToolbarCursor(
|
|||
gTooltipTimeout = 2000;
|
||||
break;
|
||||
}
|
||||
return cursorId;
|
||||
}
|
||||
|
||||
void OnUnknown5() override
|
||||
{
|
||||
InvalidateDirtyWidgets();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066C6F2
|
||||
* Creates the main game bottom toolbar window.
|
||||
*/
|
||||
static void WindowGameBottomToolbarUnknown05(WindowBase* w)
|
||||
WindowBase* WindowGameBottomToolbarOpen()
|
||||
{
|
||||
WindowGameBottomToolbarInvalidateDirtyWidgets(w);
|
||||
int32_t screenWidth = ContextGetWidth();
|
||||
int32_t screenHeight = ContextGetHeight();
|
||||
|
||||
// Figure out how much line height we have to work with.
|
||||
uint32_t line_height = FontGetLineHeight(FontStyle::Medium);
|
||||
uint32_t toolbar_height = line_height * 2 + 12;
|
||||
|
||||
GameBottomToolbar* window = WindowCreate<GameBottomToolbar>(
|
||||
WindowClass::BottomToolbar,
|
||||
ScreenCoordsXY(0, screenHeight - toolbar_height),
|
||||
screenWidth,
|
||||
toolbar_height,
|
||||
WF_STICK_TO_FRONT | WF_TRANSPARENT | WF_NO_BACKGROUND);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066C6F2
|
||||
*/
|
||||
static void WindowGameBottomToolbarInvalidateDirtyWidgets(WindowBase* w)
|
||||
void WindowGameBottomToolbarInvalidateNewsItem()
|
||||
{
|
||||
if (gToolbarDirtyFlags & BTM_TB_DIRTY_FLAG_MONEY)
|
||||
if (gScreenFlags == SCREEN_FLAGS_PLAYING)
|
||||
{
|
||||
gToolbarDirtyFlags &= ~BTM_TB_DIRTY_FLAG_MONEY;
|
||||
WidgetInvalidate(*w, WIDX_LEFT_INSET);
|
||||
WidgetInvalidateByClass(WindowClass::BottomToolbar, WIDX_MIDDLE_OUTSET);
|
||||
}
|
||||
}
|
||||
|
||||
if (gToolbarDirtyFlags & BTM_TB_DIRTY_FLAG_DATE)
|
||||
{
|
||||
gToolbarDirtyFlags &= ~BTM_TB_DIRTY_FLAG_DATE;
|
||||
WidgetInvalidate(*w, WIDX_RIGHT_INSET);
|
||||
}
|
||||
|
||||
if (gToolbarDirtyFlags & BTM_TB_DIRTY_FLAG_PEEP_COUNT)
|
||||
{
|
||||
gToolbarDirtyFlags &= ~BTM_TB_DIRTY_FLAG_PEEP_COUNT;
|
||||
WidgetInvalidate(*w, WIDX_LEFT_INSET);
|
||||
}
|
||||
|
||||
if (gToolbarDirtyFlags & BTM_TB_DIRTY_FLAG_CLIMATE)
|
||||
{
|
||||
gToolbarDirtyFlags &= ~BTM_TB_DIRTY_FLAG_CLIMATE;
|
||||
WidgetInvalidate(*w, WIDX_RIGHT_INSET);
|
||||
}
|
||||
|
||||
if (gToolbarDirtyFlags & BTM_TB_DIRTY_FLAG_PARK_RATING)
|
||||
{
|
||||
gToolbarDirtyFlags &= ~BTM_TB_DIRTY_FLAG_PARK_RATING;
|
||||
WidgetInvalidate(*w, WIDX_LEFT_INSET);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue