313 lines
11 KiB
C++
313 lines
11 KiB
C++
#include "../../CompanyManager.h"
|
|
#include "../../Graphics/ImageIds.h"
|
|
#include "../../Input.h"
|
|
#include "../../Localisation/FormatArguments.hpp"
|
|
#include "../../Objects/ObjectManager.h"
|
|
#include "../../Objects/RoadExtraObject.h"
|
|
#include "../../Objects/RoadObject.h"
|
|
#include "../../Objects/TrackExtraObject.h"
|
|
#include "../../Objects/TrackObject.h"
|
|
#include "../../Ui/Dropdown.h"
|
|
#include "../../Widget.h"
|
|
#include "Construction.h"
|
|
|
|
using namespace OpenLoco::Interop;
|
|
using namespace OpenLoco::Map;
|
|
using namespace OpenLoco::Map::TileManager;
|
|
|
|
namespace OpenLoco::Ui::Windows::Construction::Overhead
|
|
{
|
|
static loco_global<int32_t, 0x00E3F0B8> gCurrentRotation;
|
|
|
|
Widget widgets[] = {
|
|
commonWidgets(138, 192, StringIds::stringid_2),
|
|
makeWidget({ 3, 45 }, { 132, 12 }, WidgetType::checkbox, WindowColour::secondary, StringIds::empty, StringIds::tooltip_select_track_mod),
|
|
makeWidget({ 3, 57 }, { 132, 12 }, WidgetType::checkbox, WindowColour::secondary, StringIds::empty, StringIds::tooltip_select_track_mod),
|
|
makeWidget({ 3, 69 }, { 132, 12 }, WidgetType::checkbox, WindowColour::secondary, StringIds::empty, StringIds::tooltip_select_track_mod),
|
|
makeWidget({ 3, 81 }, { 132, 12 }, WidgetType::checkbox, WindowColour::secondary, StringIds::empty, StringIds::tooltip_select_track_mod),
|
|
makeWidget({ 35, 110 }, { 66, 66 }, WidgetType::wt_3, WindowColour::secondary),
|
|
makeWidget({ 3, 95 }, { 132, 12 }, WidgetType::wt_18, WindowColour::secondary, 0xFFFFFFFF, StringIds::tooltip_select_track_to_upgrade),
|
|
makeWidget({ 123, 96 }, { 11, 10 }, WidgetType::wt_11, WindowColour::secondary, StringIds::dropdown, StringIds::tooltip_select_track_to_upgrade),
|
|
widgetEnd(),
|
|
};
|
|
|
|
WindowEventList events;
|
|
|
|
// 0x0049EBD1
|
|
static void onMouseUp(Window* self, WidgetIndex_t widgetIndex)
|
|
{
|
|
switch (widgetIndex)
|
|
{
|
|
case Common::widx::close_button:
|
|
WindowManager::close(self);
|
|
break;
|
|
|
|
case Common::widx::tab_construction:
|
|
case Common::widx::tab_overhead:
|
|
case Common::widx::tab_signal:
|
|
case Common::widx::tab_station:
|
|
Common::switchTab(self, widgetIndex);
|
|
break;
|
|
|
|
case widx::checkbox_1:
|
|
case widx::checkbox_2:
|
|
case widx::checkbox_3:
|
|
case widx::checkbox_4:
|
|
{
|
|
auto checkboxIndex = widgetIndex - widx::checkbox_1;
|
|
|
|
_lastSelectedMods = _lastSelectedMods ^ (1 << checkboxIndex);
|
|
|
|
// TODO: & ~(1 << 7) added to prevent crashing when selecting/deselecting overhead wires for trams
|
|
_scenarioTrackMods[_trackType & ~(1 << 7)] = _lastSelectedMods;
|
|
|
|
self->invalidate();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 0x0049EBFC
|
|
static void onMouseDown(Window* self, WidgetIndex_t widgetIndex)
|
|
{
|
|
switch (widgetIndex)
|
|
{
|
|
case widx::track_dropdown:
|
|
{
|
|
uint8_t modCount = 3;
|
|
|
|
auto widget = self->widgets[widx::track];
|
|
auto xPos = widget.left + self->x;
|
|
auto yPos = widget.top + self->y;
|
|
auto width = widget.width() + 2;
|
|
auto height = widget.height();
|
|
|
|
Dropdown::show(xPos, yPos, width, height, self->getColour(WindowColour::secondary), modCount, (1 << 7));
|
|
|
|
Dropdown::add(0, StringIds::single_section);
|
|
Dropdown::add(1, StringIds::block_section);
|
|
Dropdown::add(2, StringIds::all_connected_track);
|
|
|
|
Dropdown::setHighlightedItem(_lastSelectedTrackModSection);
|
|
break;
|
|
}
|
|
|
|
case widx::image:
|
|
{
|
|
Input::toolCancel();
|
|
Input::toolSet(self, widgetIndex, 12);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 0x0049EC09
|
|
static void onDropdown(Window* self, WidgetIndex_t widgetIndex, int16_t itemIndex)
|
|
{
|
|
if (widgetIndex != widx::track_dropdown)
|
|
return;
|
|
|
|
if (itemIndex != -1)
|
|
{
|
|
_lastSelectedTrackModSection = itemIndex;
|
|
self->invalidate();
|
|
}
|
|
}
|
|
|
|
// 0x0049ECD1
|
|
static void onUpdate(Window* self)
|
|
{
|
|
Common::onUpdate(self, (1 << 5));
|
|
}
|
|
|
|
// 0x0049EC15
|
|
static void onToolUpdate(Window& self, const WidgetIndex_t widgetIndex, const int16_t x, const int16_t y)
|
|
{
|
|
registers regs;
|
|
regs.esi = (int32_t)&self;
|
|
regs.dx = widgetIndex;
|
|
regs.ax = x;
|
|
regs.bx = y;
|
|
call(0x0049EC15, regs);
|
|
}
|
|
|
|
// 0x0049EC20
|
|
static void onToolDown(Window& self, const WidgetIndex_t widgetIndex, const int16_t x, const int16_t y)
|
|
{
|
|
registers regs;
|
|
regs.esi = (int32_t)&self;
|
|
regs.dx = widgetIndex;
|
|
regs.ax = x;
|
|
regs.bx = y;
|
|
call(0x0049EC20, regs);
|
|
}
|
|
|
|
static void setCheckbox(Window* self, WidgetIndex_t checkboxIndex, string_id name)
|
|
{
|
|
auto widgetIndex = checkboxIndex + widx::checkbox_1;
|
|
self->widgets[widgetIndex].type = WidgetType::checkbox;
|
|
self->widgets[widgetIndex].text = name;
|
|
|
|
if (_lastSelectedMods & (1 << checkboxIndex))
|
|
self->activated_widgets |= (1ULL << widgetIndex);
|
|
}
|
|
|
|
// 0x0049E7D3
|
|
static void prepareDraw(Window* self)
|
|
{
|
|
Common::prepareDraw(self);
|
|
|
|
self->activated_widgets &= ~(1 << widx::checkbox_1 | 1 << widx::checkbox_2 | 1 << widx::checkbox_3 | 1 << widx::checkbox_4);
|
|
|
|
self->widgets[widx::checkbox_1].type = WidgetType::none;
|
|
self->widgets[widx::checkbox_2].type = WidgetType::none;
|
|
self->widgets[widx::checkbox_3].type = WidgetType::none;
|
|
self->widgets[widx::checkbox_4].type = WidgetType::none;
|
|
|
|
if (_trackType & (1 << 7))
|
|
{
|
|
auto trackType = _trackType & ~(1 << 7);
|
|
auto roadObj = ObjectManager::get<RoadObject>(trackType);
|
|
|
|
auto args = FormatArguments();
|
|
args.push(roadObj->name);
|
|
|
|
for (auto i = 0; i < 2; i++)
|
|
{
|
|
if (_modList[i] != 0xFF)
|
|
{
|
|
auto extraName = ObjectManager::get<RoadExtraObject>(_modList[i])->name;
|
|
setCheckbox(self, i, extraName);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
auto trackObj = ObjectManager::get<TrackObject>(_trackType);
|
|
|
|
auto args = FormatArguments();
|
|
args.push(trackObj->name);
|
|
|
|
for (auto i = 0; i < 4; i++)
|
|
{
|
|
if (_modList[i] != 0xFF)
|
|
{
|
|
auto extraName = ObjectManager::get<TrackExtraObject>(_modList[i])->name;
|
|
setCheckbox(self, i, extraName);
|
|
}
|
|
}
|
|
}
|
|
|
|
//self->activated_widgets = activatedWidgets;
|
|
|
|
self->widgets[widx::image].type = WidgetType::none;
|
|
self->widgets[widx::track].type = WidgetType::none;
|
|
self->widgets[widx::track_dropdown].type = WidgetType::none;
|
|
|
|
self->widgets[widx::image].tooltip = StringIds::null;
|
|
|
|
if (_lastSelectedMods & 0xF)
|
|
{
|
|
self->widgets[widx::image].type = WidgetType::wt_3;
|
|
self->widgets[widx::track].type = WidgetType::wt_18;
|
|
self->widgets[widx::track_dropdown].type = WidgetType::wt_11;
|
|
|
|
self->widgets[widx::image].tooltip = StringIds::upgrade_track_with_mods;
|
|
|
|
if (isNetworkHost())
|
|
{
|
|
if (_toolWindowType == WindowType::construction)
|
|
self->widgets[widx::image].tooltip = StringIds::click_track_to_upgrade;
|
|
}
|
|
}
|
|
|
|
static string_id modString[] = {
|
|
StringIds::single_section,
|
|
StringIds::block_section,
|
|
StringIds::all_connected_track,
|
|
};
|
|
|
|
self->widgets[widx::track].text = modString[_lastSelectedTrackModSection];
|
|
|
|
Common::repositionTabs(self);
|
|
}
|
|
|
|
// 0x0049EA3E
|
|
static void draw(Window* self, Gfx::Context* context)
|
|
{
|
|
self->draw(context);
|
|
Common::drawTabs(self, context);
|
|
if (_lastSelectedMods & 0xF)
|
|
{
|
|
Gfx::Context* clipped = nullptr;
|
|
auto xPos = self->x + self->widgets[widx::image].left + 1;
|
|
auto yPos = self->y + self->widgets[widx::image].top + 1;
|
|
auto width = self->widgets[widx::image].width();
|
|
auto height = self->widgets[widx::image].height();
|
|
|
|
if (Gfx::clipContext(&clipped, context, xPos, yPos, width, height))
|
|
{
|
|
coord_t x = 0x2010;
|
|
coord_t y = 0x2010;
|
|
|
|
auto rotCoord = rotate2dCoordinate({ x, y }, gCurrentRotation);
|
|
Gfx::point_t screenPos = { static_cast<int16_t>(rotCoord.y - rotCoord.x), static_cast<int16_t>(((rotCoord.x + rotCoord.y) >> 1) - 460) };
|
|
|
|
screenPos.x -= (self->widgets[widx::image].width() / 2);
|
|
screenPos.y -= ((self->widgets[widx::image].width() / 2) + 16);
|
|
clipped->x += screenPos.x;
|
|
clipped->y += screenPos.y;
|
|
|
|
_dword_E0C3E0 = clipped;
|
|
|
|
x = 0x2000;
|
|
y = 0x2000;
|
|
|
|
auto company = CompanyManager::get(_playerCompany);
|
|
auto companyColour = company->mainColours.primary;
|
|
_byte_522095 = _byte_522095 | (1 << 0);
|
|
|
|
if (_trackType & (1 << 7))
|
|
{
|
|
uint8_t trackType = _trackType & ~(1 << 7);
|
|
Construction::drawRoad(x, y, _lastSelectedMods, 0x1D0, trackType, 0, companyColour, gCurrentRotation);
|
|
}
|
|
else
|
|
{
|
|
Construction::drawTrack(x, y, _lastSelectedMods, 0x1D0, _trackType, 0, companyColour, gCurrentRotation);
|
|
}
|
|
_byte_522095 = _byte_522095 & ~(1 << 0);
|
|
}
|
|
}
|
|
|
|
auto xPos = self->x + 69;
|
|
auto yPos = self->widgets[widx::image].bottom + self->y + 4;
|
|
|
|
if (_modCost != 0x80000000 && _modCost != 0)
|
|
{
|
|
auto args = FormatArguments();
|
|
args.push<uint32_t>(_modCost);
|
|
|
|
Gfx::drawStringCentred(*context, xPos, yPos, Colour::black, StringIds::build_cost, &args);
|
|
}
|
|
}
|
|
|
|
void tabReset(Window* self)
|
|
{
|
|
self->callOnMouseDown(Overhead::widx::image);
|
|
}
|
|
|
|
void initEvents()
|
|
{
|
|
events.on_close = Common::onClose;
|
|
events.on_mouse_up = onMouseUp;
|
|
events.on_mouse_down = onMouseDown;
|
|
events.on_dropdown = onDropdown;
|
|
events.on_update = onUpdate;
|
|
events.on_tool_update = onToolUpdate;
|
|
events.on_tool_down = onToolDown;
|
|
events.prepare_draw = prepareDraw;
|
|
events.draw = draw;
|
|
}
|
|
}
|