Construction Window (#493)
* Initial work on open function * Further Setup * Further Progress * Fix Window crashing on open * Implement on dropdown, on_resize and cursor for construction tab * Implement on_mouse_down for construction tab * Further Work on Construction Tab * Fix track construction tool not working * Implement disabled widgets for track selection * Start work on 2nd Tab events * Finish Station Tab * Implement Events for signal Tab * Implement 4th Tab events * Fix window not displaying track and crash on selecting road bridge * Minor Formatting * Progress on construction on_tool_down * Fix crash on construction _on_tool_down * Implement on_tool_down * Refactor construction_draw * Fixes for CI * Fix Station Catchment being permanently displayed * Run clang format * Split tabs into seperate files * Fix for CI * Fix Window not drawing on open * Fix for CI * Fix window crashing due to incorrect station type * Replace while loops with for loops in Station and Signal Tabs * Refactor Station Dropdown loops into Templated function * Refactor ConstructionTab.cpp * Fixes for CI * Fix crash to desktop when constructing underground * Fix incorrect tiles highlighting on tool update * Fix for Xcode * Fix crash to desktop when opening tram track construction window
This commit is contained in:
parent
e510ced11f
commit
be8bfa37e6
|
@ -76,4 +76,11 @@ namespace openloco
|
|||
args.push(performanceIndex);
|
||||
args.push(getCorporateRatingAsStringId(performanceToRating(performanceIndex)));
|
||||
}
|
||||
|
||||
bool company::isVehicleIndexUnlocked(const uint8_t vehicleIndex) const
|
||||
{
|
||||
auto vehicleTypeIndex = vehicleIndex >> 5;
|
||||
|
||||
return (unlocked_vehicles[vehicleTypeIndex] & (1 << (vehicleIndex & 0x1F))) != 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ namespace openloco
|
|||
company_id_t id() const;
|
||||
bool empty() const;
|
||||
void ai_think();
|
||||
bool isVehicleIndexUnlocked(const uint8_t vehicleIndex) const;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
|
|
@ -21,6 +21,31 @@ namespace openloco::image_ids
|
|||
constexpr uint32_t inline_green_up_arrow = 2324;
|
||||
constexpr uint32_t inline_red_down_arrow = 2325;
|
||||
|
||||
constexpr uint32_t construction_straight = 2335;
|
||||
|
||||
constexpr uint32_t construction_left_hand_curve_very_small = 2340;
|
||||
constexpr uint32_t construction_right_hand_curve_very_small = 2341;
|
||||
constexpr uint32_t construction_left_hand_curve_small = 2342;
|
||||
constexpr uint32_t construction_right_hand_curve_small = 2343;
|
||||
constexpr uint32_t construction_left_hand_curve = 2344;
|
||||
constexpr uint32_t construction_right_hand_curve = 2345;
|
||||
constexpr uint32_t construction_left_hand_curve_large = 2346;
|
||||
constexpr uint32_t construction_right_hand_curve_large = 2347;
|
||||
constexpr uint32_t construction_steep_slope_down = 2348;
|
||||
constexpr uint32_t construction_slope_down = 2349;
|
||||
constexpr uint32_t construction_level = 2350;
|
||||
constexpr uint32_t construction_slope_up = 2351;
|
||||
constexpr uint32_t construction_steep_slope_up = 2352;
|
||||
constexpr uint32_t construction_s_bend_left = 2353;
|
||||
constexpr uint32_t construction_s_bend_right = 2354;
|
||||
constexpr uint32_t construction_s_bend_dual_track_left = 2355;
|
||||
constexpr uint32_t construction_s_bend_dual_track_right = 2356;
|
||||
constexpr uint32_t construction_s_bend_to_single_track_left = 2357;
|
||||
constexpr uint32_t construction_s_bend_to_single_track_right = 2358;
|
||||
constexpr uint32_t construction_right_turnaround = 2359;
|
||||
constexpr uint32_t construction_left_turnaround = 2360;
|
||||
constexpr uint32_t construction_remove = 2361;
|
||||
constexpr uint32_t construction_new_position = 2362;
|
||||
constexpr uint32_t rubbish_bin = 2363;
|
||||
constexpr uint32_t centre_viewport = 2364;
|
||||
constexpr uint32_t rotate_object = 2365;
|
||||
|
|
|
@ -52,6 +52,11 @@ namespace openloco::input
|
|||
VSCROLLBAR_DOWN_PRESSED = (1 << 7),
|
||||
};
|
||||
|
||||
namespace map_selection_flags
|
||||
{
|
||||
constexpr uint8_t catchment_area = 1 << 5;
|
||||
};
|
||||
|
||||
namespace key_modifier
|
||||
{
|
||||
constexpr uint8_t shift = 1 << 0;
|
||||
|
@ -87,6 +92,9 @@ namespace openloco::input
|
|||
|
||||
bool has_key_modifier(uint8_t modifier);
|
||||
uint16_t getMapSelectionFlags();
|
||||
bool hasMapSelectionFlag(uint8_t flags);
|
||||
void setMapSelectionFlags(uint8_t flags);
|
||||
void resetMapSelectionFlag(uint8_t flags);
|
||||
|
||||
void handle_keyboard();
|
||||
void handle_mouse(int16_t x, int16_t y, mouse_button button);
|
||||
|
|
|
@ -281,6 +281,21 @@ namespace openloco::input
|
|||
return _mapSelectionFlags;
|
||||
}
|
||||
|
||||
bool hasMapSelectionFlag(uint8_t flags)
|
||||
{
|
||||
return (_mapSelectionFlags & flags) != 0;
|
||||
}
|
||||
|
||||
void setMapSelectionFlags(uint8_t flags)
|
||||
{
|
||||
_mapSelectionFlags = _mapSelectionFlags | flags;
|
||||
}
|
||||
|
||||
void resetMapSelectionFlag(uint8_t flags)
|
||||
{
|
||||
_mapSelectionFlags = _mapSelectionFlags & ~flags;
|
||||
}
|
||||
|
||||
#pragma mark - Mouse input
|
||||
|
||||
// 0x004C7174
|
||||
|
|
|
@ -706,15 +706,6 @@ void openloco::interop::register_hooks()
|
|||
return 0;
|
||||
});
|
||||
|
||||
register_hook(
|
||||
0x0049D3F6,
|
||||
[](registers& regs) FORCE_ALIGN_ARG_POINTER -> uint8_t {
|
||||
registers backup = regs;
|
||||
ui::windows::construction::on_mouse_up(*((ui::window*)regs.esi), regs.dx);
|
||||
regs = backup;
|
||||
return 0;
|
||||
});
|
||||
|
||||
register_hook(
|
||||
0x004BA8D4,
|
||||
[](registers& regs) FORCE_ALIGN_ARG_POINTER -> uint8_t {
|
||||
|
@ -775,6 +766,7 @@ void openloco::interop::register_hooks()
|
|||
ui::build_vehicle::registerHooks();
|
||||
ui::windows::terraform::registerHooks();
|
||||
ui::windows::error::registerHooks();
|
||||
ui::windows::construction::registerHooks();
|
||||
ui::WindowManager::registerHooks();
|
||||
ui::viewportmgr::registerHooks();
|
||||
game_commands::registerHooks();
|
||||
|
|
|
@ -108,6 +108,31 @@ namespace openloco::string_ids
|
|||
constexpr string_id screenshot_saved_as = 109;
|
||||
constexpr string_id screenshot_failed = 110;
|
||||
|
||||
constexpr string_id stringid_2 = 113;
|
||||
constexpr string_id tooltip_left_hand_curve = 114;
|
||||
constexpr string_id tooltip_right_hand_curve = 115;
|
||||
constexpr string_id tooltip_left_hand_curve_small = 116;
|
||||
constexpr string_id tooltip_right_hand_curve_small = 117;
|
||||
constexpr string_id tooltip_left_hand_curve_very_small = 118;
|
||||
constexpr string_id tooltip_right_hand_curve_very_small = 119;
|
||||
constexpr string_id tooltip_left_hand_curve_large = 120;
|
||||
constexpr string_id tooltip_right_hand_curve_large = 121;
|
||||
constexpr string_id tooltip_straight = 122;
|
||||
constexpr string_id tooltip_s_bend_left = 123;
|
||||
constexpr string_id tooltip_s_bend_right = 124;
|
||||
constexpr string_id tooltip_s_bend_left_dual_track = 125;
|
||||
constexpr string_id tooltip_s_bend_right_dual_track = 126;
|
||||
constexpr string_id tooltip_s_bend_to_single_track = 127;
|
||||
constexpr string_id tooltip_turnaround = 128;
|
||||
constexpr string_id tooltip_start_construction = 129;
|
||||
constexpr string_id tooltip_construct = 130;
|
||||
constexpr string_id tooltip_remove = 131;
|
||||
constexpr string_id tooltip_steep_slope_down = 132;
|
||||
constexpr string_id tooltip_slope_down = 133;
|
||||
constexpr string_id tooltip_level = 134;
|
||||
constexpr string_id tooltip_slope_up = 135;
|
||||
constexpr string_id tooltip_steep_slope_up = 136;
|
||||
constexpr string_id build_this = 137;
|
||||
constexpr string_id build_cost = 138;
|
||||
|
||||
constexpr string_id menu_underground_view = 145;
|
||||
|
@ -187,13 +212,37 @@ namespace openloco::string_ids
|
|||
constexpr string_id title_company_colour_scheme = 250;
|
||||
constexpr string_id title_company_challenge = 251;
|
||||
|
||||
constexpr string_id velocity = 263;
|
||||
constexpr string_id unlimited_speed = 264;
|
||||
|
||||
constexpr string_id tooltip_select_track_to_upgrade = 268;
|
||||
|
||||
constexpr string_id signal_black = 270;
|
||||
constexpr string_id tab_track_road_construction = 271;
|
||||
constexpr string_id tab_station_construction = 272;
|
||||
constexpr string_id tab_signal_construction = 273;
|
||||
constexpr string_id tab_electrification_construction = 274;
|
||||
constexpr string_id tooltip_select_signal_type = 275;
|
||||
constexpr string_id tooltip_signal_both_directions = 276;
|
||||
constexpr string_id tooltip_signal_single_direction = 277;
|
||||
constexpr string_id tooltip_bridge_stats = 278;
|
||||
constexpr string_id tooltip_select_station_type = 279;
|
||||
|
||||
constexpr string_id buffer_337 = 337;
|
||||
constexpr string_id buffer_338 = 338;
|
||||
|
||||
constexpr string_id stringid_stringid = 347;
|
||||
constexpr string_id single_section = 348;
|
||||
constexpr string_id block_section = 349;
|
||||
constexpr string_id all_connected_track = 350;
|
||||
|
||||
constexpr string_id upgrade_track_with_mods = 352;
|
||||
constexpr string_id click_track_to_upgrade = 353;
|
||||
constexpr string_id tooltip_select_track_mod = 354;
|
||||
constexpr string_id move_main_view_to_show_this = 355;
|
||||
|
||||
constexpr string_id error_can_only_build_above_ground = 360;
|
||||
|
||||
constexpr string_id title_station_name = 383;
|
||||
constexpr string_id prompt_type_new_station_name = 384;
|
||||
constexpr string_id error_cant_rename_station = 385;
|
||||
|
@ -251,6 +300,9 @@ namespace openloco::string_ids
|
|||
constexpr string_id player_info_company_value = 572;
|
||||
constexpr string_id player_info_company_value_negative = 573;
|
||||
|
||||
constexpr string_id new_construction_position = 579;
|
||||
constexpr string_id rotate_90 = 580;
|
||||
|
||||
constexpr string_id error_cant_build_this_here = 583;
|
||||
constexpr string_id date_monthyear = 584;
|
||||
|
||||
|
@ -645,6 +697,11 @@ namespace openloco::string_ids
|
|||
constexpr string_id prompt_type_new_town_name = 1309;
|
||||
constexpr string_id status_town_population = 1310;
|
||||
constexpr string_id error_cant_rename_town = 1311;
|
||||
constexpr string_id new_station = 1312;
|
||||
constexpr string_id new_station_buffer = 1313;
|
||||
constexpr string_id catchment_area_accepts = 1314;
|
||||
constexpr string_id catchment_area_produces = 1315;
|
||||
constexpr string_id catchment_area_nothing = 1316;
|
||||
|
||||
constexpr string_id title_industries = 1318;
|
||||
constexpr string_id title_fund_new_industries = 1319;
|
||||
|
@ -804,6 +861,8 @@ namespace openloco::string_ids
|
|||
constexpr string_id forbid_trams = 1521;
|
||||
constexpr string_id forbid_aircraft = 1522;
|
||||
constexpr string_id forbid_ships = 1523;
|
||||
constexpr string_id title_airport = 1524;
|
||||
constexpr string_id title_ship_port = 1525;
|
||||
|
||||
constexpr string_id currently_playing = 1535;
|
||||
constexpr string_id music_controls_stop_tip = 1536;
|
||||
|
@ -1088,6 +1147,7 @@ namespace openloco::string_ids
|
|||
constexpr string_id title_industry_name = 2017;
|
||||
constexpr string_id prompt_enter_new_industry_name = 2018;
|
||||
constexpr string_id error_cant_rename_industry = 2019;
|
||||
constexpr string_id dropdown_bridge_stats = 2020;
|
||||
|
||||
constexpr string_id position_1st = 2023;
|
||||
constexpr string_id position_2nd = 2024;
|
||||
|
|
|
@ -167,4 +167,31 @@ namespace openloco::map
|
|||
|
||||
return coordinate_2d;
|
||||
}
|
||||
|
||||
map_pos rotate2DCoordinate(map_pos pos, uint8_t rotation)
|
||||
{
|
||||
map_pos coordinate2D;
|
||||
|
||||
switch (rotation)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
coordinate2D = pos;
|
||||
break;
|
||||
case 1:
|
||||
coordinate2D.x = pos.y;
|
||||
coordinate2D.y = -pos.x;
|
||||
break;
|
||||
case 2:
|
||||
coordinate2D.x = -pos.x;
|
||||
coordinate2D.y = -pos.y;
|
||||
break;
|
||||
case 3:
|
||||
coordinate2D.x = -pos.y;
|
||||
coordinate2D.y = pos.x;
|
||||
break;
|
||||
}
|
||||
|
||||
return coordinate2D;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ namespace openloco::map
|
|||
|
||||
uint32_t tile_element_height(int16_t x, int16_t y);
|
||||
map_pos coordinate_3d_to_2d(int16_t x, int16_t y, int16_t z, int rotation);
|
||||
map_pos rotate2DCoordinate(map_pos pos, uint8_t rotation);
|
||||
|
||||
enum class element_type
|
||||
{
|
||||
|
|
|
@ -7,12 +7,6 @@ using namespace openloco::interop;
|
|||
|
||||
namespace openloco::map::tilemgr
|
||||
{
|
||||
enum MapSelectFlag : uint16_t
|
||||
{
|
||||
enable = (1 << 0),
|
||||
enableConstruct = (1 << 1)
|
||||
};
|
||||
|
||||
static loco_global<tile_element* [0x30004], 0x00E40134> _tiles;
|
||||
static loco_global<coord_t, 0x00F24486> _mapSelectionAX;
|
||||
static loco_global<coord_t, 0x00F24488> _mapSelectionBX;
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
|
||||
namespace openloco::map::tilemgr
|
||||
{
|
||||
enum MapSelectFlag : uint16_t
|
||||
{
|
||||
enable = (1 << 0),
|
||||
enableConstruct = (1 << 1)
|
||||
};
|
||||
|
||||
tile get(map_pos pos);
|
||||
tile get(coord_t x, coord_t y);
|
||||
std::tuple<int16_t, int16_t> get_height(coord_t x, coord_t y);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../localisation/stringmgr.h"
|
||||
#include "../types.hpp"
|
||||
|
||||
namespace openloco
|
||||
{
|
||||
|
@ -26,10 +26,25 @@ namespace openloco
|
|||
struct airport_object
|
||||
{
|
||||
string_id name;
|
||||
uint8_t pad_02[0x10 - 0x02];
|
||||
uint16_t var_10;
|
||||
uint8_t pad_12[0xAD - 0x12];
|
||||
uint8_t var_AD;
|
||||
uint16_t build_cost_factor; // 0x02
|
||||
uint16_t sell_cost_factor; // 0x04
|
||||
uint8_t cost_index; //0x06
|
||||
uint8_t var_07;
|
||||
uint32_t var_08;
|
||||
uint8_t pad_0C[0x10 - 0x0C];
|
||||
uint16_t allowed_plane_types; // 0x10
|
||||
uint8_t num_sprite_sets; // 0x12
|
||||
uint8_t num_tiles; // 0x13
|
||||
uint8_t pad_14[0xA0 - 0x14];
|
||||
uint32_t large_tiles; // 0xA0
|
||||
uint8_t min_x; // 0xA4
|
||||
uint8_t min_y; // 0xA5
|
||||
uint8_t max_x; // 0xA6
|
||||
uint8_t max_y; // 0xA7
|
||||
uint16_t designed_year; // 0xA8
|
||||
uint16_t obsolete_year; // 0xAA
|
||||
uint8_t num_nodes; // 0xAC
|
||||
uint8_t num_edges; // 0xAD
|
||||
airport_var_AE_object* var_AE;
|
||||
airport_var_B2_object* var_B2;
|
||||
uint8_t pad_B6[0xBA - 0xB6];
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include "../types.hpp"
|
||||
|
||||
namespace openloco
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
struct bridge_object
|
||||
{
|
||||
string_id name;
|
||||
uint8_t no_roof; // 0x02
|
||||
uint8_t pad_03[0x08 - 0x03];
|
||||
uint8_t span_length; // 0x08
|
||||
uint8_t pillar_spacing; // 0x09
|
||||
uint16_t max_speed; // 0x0A
|
||||
uint8_t max_height; // 0x0C
|
||||
uint8_t cost_index; // 0x0D
|
||||
uint16_t base_cost_factor; // 0x0E
|
||||
uint16_t height_cost_factor; // 0x10
|
||||
uint16_t sell_cost_factor; // 0x12
|
||||
uint16_t disabled_track_cfg; // 0x14
|
||||
uint32_t var_16;
|
||||
uint8_t track_num_compatible; // 0x1A
|
||||
uint8_t track_mods[7]; // 0x1B
|
||||
uint8_t road_num_compatible; // 0x22
|
||||
uint8_t road_mods[7]; // 0x23
|
||||
uint16_t designed_year; // 0x2A
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include "../types.hpp"
|
||||
|
||||
namespace openloco
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
struct dock_object
|
||||
{
|
||||
string_id name;
|
||||
uint16_t build_cost_factor; // 0x02
|
||||
uint16_t sell_cost_factor; // 0x04
|
||||
uint8_t cost_index; // 0x06
|
||||
uint8_t var_07;
|
||||
uint32_t var_08;
|
||||
uint8_t pad_0C[0x12 - 0x0C];
|
||||
uint8_t num_aux_01; // 0x12
|
||||
uint8_t num_aux_02_ent; // 0x13
|
||||
uint8_t pad_14[0x20 - 0x14];
|
||||
uint16_t designed_year; // 0x20
|
||||
uint16_t obsolete_year; // 0x22
|
||||
uint8_t pad_24[0x28 - 0x24];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
|
@ -80,16 +80,31 @@ namespace openloco::objectmgr
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
template<>
|
||||
train_signal_object* get(size_t id)
|
||||
{
|
||||
if (_trainSignalObjects[id] != reinterpret_cast<train_signal_object*>(-1))
|
||||
return _trainSignalObjects[id];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<>
|
||||
road_station_object* get(size_t id)
|
||||
{
|
||||
return _roadStationObjects[id];
|
||||
if (_roadStationObjects[id] != reinterpret_cast<road_station_object*>(-1))
|
||||
return _roadStationObjects[id];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<>
|
||||
vehicle_object* get(size_t id)
|
||||
{
|
||||
return _vehicleObjects[id];
|
||||
if (_vehicleObjects[id] != reinterpret_cast<vehicle_object*>(-1))
|
||||
return _vehicleObjects[id];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -122,7 +137,7 @@ namespace openloco::objectmgr
|
|||
template<>
|
||||
industry_object* get(size_t id)
|
||||
{
|
||||
if (_industryObjects[id] != (industry_object*)-1)
|
||||
if (_industryObjects[id] != reinterpret_cast<industry_object*>(-1))
|
||||
return _industryObjects[id];
|
||||
else
|
||||
return nullptr;
|
||||
|
@ -134,6 +149,24 @@ namespace openloco::objectmgr
|
|||
return _currencyObjects[0];
|
||||
}
|
||||
|
||||
template<>
|
||||
bridge_object* get(size_t id)
|
||||
{
|
||||
if (_bridgeObjects[id] != reinterpret_cast<bridge_object*>(-1))
|
||||
return _bridgeObjects[id];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<>
|
||||
train_station_object* get(size_t id)
|
||||
{
|
||||
if (_trainStationObjects[id] != reinterpret_cast<train_station_object*>(-1))
|
||||
return _trainStationObjects[id];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<>
|
||||
track_extra_object* get(size_t id)
|
||||
{
|
||||
|
@ -143,7 +176,10 @@ namespace openloco::objectmgr
|
|||
template<>
|
||||
track_object* get(size_t id)
|
||||
{
|
||||
return _trackObjects[id];
|
||||
if (_trackObjects[id] != reinterpret_cast<track_object*>(-1))
|
||||
return _trackObjects[id];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -155,13 +191,28 @@ namespace openloco::objectmgr
|
|||
template<>
|
||||
road_object* get(size_t id)
|
||||
{
|
||||
return _roadObjects[id];
|
||||
if (_roadObjects[id] != reinterpret_cast<road_object*>(-1))
|
||||
return _roadObjects[id];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<>
|
||||
airport_object* get(size_t id)
|
||||
{
|
||||
return _airportObjects[id];
|
||||
if (_airportObjects[id] != reinterpret_cast<airport_object*>(-1))
|
||||
return _airportObjects[id];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<>
|
||||
dock_object* get(size_t id)
|
||||
{
|
||||
if (_dockObjects[id] != reinterpret_cast<dock_object*>(-1))
|
||||
return _dockObjects[id];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
|
@ -147,6 +147,8 @@ namespace openloco::objectmgr
|
|||
template<>
|
||||
cargo_object* get(size_t id);
|
||||
template<>
|
||||
train_signal_object* get(size_t id);
|
||||
template<>
|
||||
road_station_object* get(size_t id);
|
||||
template<>
|
||||
vehicle_object* get(size_t id);
|
||||
|
@ -161,12 +163,18 @@ namespace openloco::objectmgr
|
|||
template<>
|
||||
currency_object* get();
|
||||
template<>
|
||||
bridge_object* get();
|
||||
template<>
|
||||
train_station_object* get();
|
||||
template<>
|
||||
track_object* get(size_t id);
|
||||
template<>
|
||||
road_object* get(size_t id);
|
||||
template<>
|
||||
airport_object* get(size_t id);
|
||||
template<>
|
||||
dock_object* get(size_t id);
|
||||
template<>
|
||||
land_object* get(size_t id);
|
||||
template<>
|
||||
water_object* get();
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include "../localisation/stringmgr.h"
|
||||
#include "../types.hpp"
|
||||
|
||||
namespace openloco
|
||||
{
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct road_extra_object
|
||||
{
|
||||
string_id name;
|
||||
uint16_t road_pieces; // 0x02
|
||||
uint8_t is_overhead; // 0x04
|
||||
uint8_t cost_index; // 0x05
|
||||
uint16_t build_cost_factor; // 0x06
|
||||
uint16_t sell_cost_factor; // 0x08
|
||||
uint8_t pad_0A[0x0E - 0x0A];
|
||||
uint32_t var_0E;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../localisation/stringmgr.h"
|
||||
#include "../types.hpp"
|
||||
|
||||
namespace openloco
|
||||
{
|
||||
|
@ -9,14 +9,39 @@ namespace openloco
|
|||
constexpr uint8_t unk_01 = 1 << 1;
|
||||
constexpr uint8_t unk_03 = 1 << 3;
|
||||
}
|
||||
|
||||
namespace road_piece_flags
|
||||
{
|
||||
constexpr uint16_t one_way = 1 << 0;
|
||||
constexpr uint16_t track = 1 << 1;
|
||||
constexpr uint16_t slope = 1 << 2;
|
||||
constexpr uint16_t steep_slope = 1 << 3;
|
||||
constexpr uint16_t intersection = 1 << 2;
|
||||
constexpr uint16_t one_sided = 1 << 5;
|
||||
constexpr uint16_t overtake = 1 << 6;
|
||||
constexpr uint16_t street_lights = 1 << 8;
|
||||
}
|
||||
#pragma pack(push, 1)
|
||||
struct road_object
|
||||
{
|
||||
string_id name;
|
||||
uint8_t pad_02[0x0E - 0x02];
|
||||
uint16_t road_pieces; // 0x02
|
||||
uint16_t build_cost_factor; // 0x04
|
||||
uint16_t sell_cost_factor; // 0x06
|
||||
uint16_t tunnel_cost_factor; // 0x08
|
||||
uint8_t cost_index; // 0x0A
|
||||
uint8_t pad_0B[0x0E - 0x0B];
|
||||
uint32_t var_0E;
|
||||
uint16_t flags; //0x12
|
||||
uint8_t pad_14[0x30 - 0x14];
|
||||
uint16_t flags; // 0x12
|
||||
uint8_t num_bridges; // 0x14
|
||||
uint8_t bridges[7]; // 0x15
|
||||
uint8_t num_stations; // 0x1C
|
||||
uint8_t stations[7]; // 0x1D
|
||||
uint8_t var_24;
|
||||
uint8_t num_mods; // 0x25
|
||||
uint8_t mods[2]; // 0x26
|
||||
uint8_t num_compatible; // 0x28
|
||||
uint8_t pad_29[0x30 - 0x29];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
||||
|
|
|
@ -1,17 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include "../localisation/stringmgr.h"
|
||||
#include "../types.hpp"
|
||||
|
||||
namespace openloco
|
||||
{
|
||||
namespace road_station_flags
|
||||
{
|
||||
constexpr uint8_t recolourable = 1 << 0;
|
||||
}
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct road_station_object
|
||||
{
|
||||
string_id name;
|
||||
uint8_t pad_02[0x0B - 0x02];
|
||||
uint8_t var_0B;
|
||||
uint8_t pad_0C[0x2C - 0x0C];
|
||||
uint8_t var_2C;
|
||||
uint8_t pad_02[0x04 - 0x02];
|
||||
uint16_t road_pieces; // 0x04
|
||||
uint16_t build_cost_factor; // 0x06
|
||||
uint16_t sell_cost_factor; // 0x08
|
||||
uint8_t cost_index; // 0x0A
|
||||
uint8_t flags; // 0x0B
|
||||
uint32_t var_0C;
|
||||
uint8_t pad_10[0x20 - 0x10];
|
||||
uint8_t num_compatible; // 0x20
|
||||
uint8_t mods[7]; // 0x21
|
||||
uint16_t designed_year; // 0x28
|
||||
uint16_t obsolete_year; // 0x2A
|
||||
uint8_t pad_2C[0x6E - 0x2C];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../localisation/stringmgr.h"
|
||||
#include "../types.hpp"
|
||||
|
||||
namespace openloco
|
||||
{
|
||||
|
@ -9,6 +9,13 @@ namespace openloco
|
|||
struct track_extra_object
|
||||
{
|
||||
string_id name;
|
||||
uint16_t track_pieces; // 0x02
|
||||
uint8_t is_overhead; // 0x04
|
||||
uint8_t cost_index; // 0x05
|
||||
uint16_t build_cost_factor; // 0x06
|
||||
uint16_t sell_cost_factor; // 0x08
|
||||
uint8_t pad_0A[0x0E - 0x0A];
|
||||
uint32_t var_0E;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../localisation/stringmgr.h"
|
||||
#include "../types.hpp"
|
||||
|
||||
namespace openloco
|
||||
{
|
||||
|
@ -8,13 +8,48 @@ namespace openloco
|
|||
{
|
||||
constexpr uint8_t unk_02 = 1 << 2;
|
||||
}
|
||||
|
||||
namespace track_piece_flags
|
||||
{
|
||||
constexpr uint16_t diagonal = 1 << 0;
|
||||
constexpr uint16_t large_curve = 1 << 1;
|
||||
constexpr uint16_t normal_curve = 1 << 2;
|
||||
constexpr uint16_t small_curve = 1 << 3;
|
||||
constexpr uint16_t very_small_curve = 1 << 4;
|
||||
constexpr uint16_t slope = 1 << 5;
|
||||
constexpr uint16_t steep_slope = 1 << 6;
|
||||
constexpr uint16_t one_sided = 1 << 7;
|
||||
constexpr uint16_t sloped_curve = 1 << 8;
|
||||
constexpr uint16_t s_bend = 1 << 9;
|
||||
constexpr uint16_t junction = 1 << 10;
|
||||
}
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct track_object
|
||||
{
|
||||
string_id name;
|
||||
uint8_t pad_02[0x1E - 0x02];
|
||||
uint16_t track_pieces; // 0x02
|
||||
uint16_t station_track_pieces; // 0x04
|
||||
uint8_t var_06;
|
||||
uint8_t num_compatible; // 0x07
|
||||
uint8_t num_mods; // 0x08
|
||||
uint8_t num_signals; // 0x09
|
||||
uint8_t mods[4]; // 0x0A
|
||||
uint8_t var_0E;
|
||||
uint8_t pad_0F[0x14 - 0x0F];
|
||||
uint16_t build_cost_factor; // 0x14
|
||||
uint16_t sell_cost_factor; // 0x16
|
||||
uint16_t tunnel_cost_factor; // 0x18
|
||||
uint8_t cost_index; // 0x1A
|
||||
uint8_t var_1B;
|
||||
uint16_t curve_speed; // 0x1C
|
||||
uint32_t var_1E;
|
||||
uint16_t flags; // 0x22
|
||||
uint16_t flags; // 0x22
|
||||
uint8_t num_bridges; // 0x24
|
||||
uint8_t bridges[7]; // 0x25
|
||||
uint8_t num_stations; // 0x2C
|
||||
uint8_t stations[7]; // 0x2D
|
||||
uint8_t display_offset; // 0x34
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
#include "../types.hpp"
|
||||
|
||||
namespace openloco
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
struct train_signal_object
|
||||
{
|
||||
string_id name;
|
||||
uint16_t track_side; // 0x02
|
||||
uint8_t var_04;
|
||||
uint8_t num_frames; // 0x05
|
||||
uint16_t cost_factor; // 0x06
|
||||
uint16_t sell_cost_factor; // 0x08
|
||||
uint8_t cost_index; // 0x0A
|
||||
uint8_t var_0B;
|
||||
uint16_t var_0C;
|
||||
uint32_t var_0E;
|
||||
uint8_t num_compatible; // 0x12
|
||||
uint8_t mods[7]; // 0x13
|
||||
uint16_t designed_year; // 0x1A
|
||||
uint16_t obsolete_year; // 0x1C
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
|
||||
#include "../types.hpp"
|
||||
|
||||
namespace openloco
|
||||
{
|
||||
namespace train_station_flags
|
||||
{
|
||||
constexpr uint8_t recolourable = 1 << 0;
|
||||
}
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct train_station_object
|
||||
{
|
||||
string_id name;
|
||||
uint8_t var_02;
|
||||
uint8_t var_03;
|
||||
uint16_t track_pieces; // 0x04
|
||||
uint16_t build_cost_factor; // 0x06
|
||||
uint16_t sell_cost_factor; // 0x08
|
||||
uint8_t cost_index; // 0x0A
|
||||
uint8_t var_0B;
|
||||
uint8_t flags; // 0x0C
|
||||
uint8_t var_0D;
|
||||
uint32_t var_0E;
|
||||
uint8_t pad_12[0x22 - 0x12];
|
||||
uint8_t num_compatible; // 0x22
|
||||
uint8_t mods[7];
|
||||
uint16_t designed_year; // 0x2A
|
||||
uint16_t obsolete_year; // 0x2C
|
||||
uint8_t var_2E[16];
|
||||
uint8_t var_3E[16];
|
||||
uint8_t var_4E[16];
|
||||
uint8_t var_5E[16];
|
||||
uint8_t pad_6E[0xAC - 0x6E];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
|
@ -139,6 +139,11 @@ namespace openloco
|
|||
return (_screen_flags & screen_flags::networked) != 0;
|
||||
}
|
||||
|
||||
bool isTrackUpgradeMode()
|
||||
{
|
||||
return (_screen_flags & screen_flags::trackUpgrade) != 0;
|
||||
}
|
||||
|
||||
bool is_unknown_4_mode()
|
||||
{
|
||||
return (_screen_flags & screen_flags::unknown_4) != 0;
|
||||
|
@ -388,7 +393,7 @@ namespace openloco
|
|||
}
|
||||
|
||||
// Host/client?
|
||||
if ((get_screen_flags() & screen_flags::unknown_3) != 0)
|
||||
if (isTrackUpgradeMode())
|
||||
{
|
||||
_updating_company_id = companymgr::get_controlling_id();
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace openloco
|
|||
constexpr uint8_t title = 1 << 0;
|
||||
constexpr uint8_t editor = 1 << 1;
|
||||
constexpr uint8_t networked = 1 << 2;
|
||||
constexpr uint8_t unknown_3 = 1 << 3;
|
||||
constexpr uint8_t trackUpgrade = 1 << 3;
|
||||
constexpr uint8_t unknown_4 = 1 << 4;
|
||||
constexpr uint8_t unknown_5 = 1 << 5;
|
||||
constexpr uint8_t unknown_6 = 1 << 6;
|
||||
|
@ -30,6 +30,7 @@ namespace openloco
|
|||
bool is_editor_mode();
|
||||
bool is_title_mode();
|
||||
bool isNetworked();
|
||||
bool isTrackUpgradeMode();
|
||||
bool is_unknown_4_mode();
|
||||
bool is_paused();
|
||||
uint8_t get_pause_flags();
|
||||
|
|
|
@ -92,7 +92,11 @@
|
|||
<ClCompile Include="windows\CompanyFaceSelection.cpp" />
|
||||
<ClCompile Include="windows\CompanyList.cpp" />
|
||||
<ClCompile Include="windows\CompanyWindow.cpp" />
|
||||
<ClCompile Include="windows\constructionwnd.cpp" />
|
||||
<ClCompile Include="windows\construction\Common.cpp" />
|
||||
<ClCompile Include="windows\construction\ConstructionTab.cpp" />
|
||||
<ClCompile Include="windows\construction\OverheadTab.cpp" />
|
||||
<ClCompile Include="windows\construction\SignalTab.cpp" />
|
||||
<ClCompile Include="windows\construction\StationTab.cpp" />
|
||||
<ClCompile Include="windows\EditKeyboardShortcut.cpp" />
|
||||
<ClCompile Include="windows\Error.cpp" />
|
||||
<ClCompile Include="windows\IndustryWindow.cpp" />
|
||||
|
@ -175,10 +179,12 @@
|
|||
<ClInclude Include="messagemgr.h" />
|
||||
<ClInclude Include="multiplayer.h" />
|
||||
<ClInclude Include="objects\airport_object.h" />
|
||||
<ClInclude Include="objects\bridge_object.h" />
|
||||
<ClInclude Include="objects\building_object.h" />
|
||||
<ClInclude Include="objects\cargo_object.h" />
|
||||
<ClInclude Include="objects\competitor_object.h" />
|
||||
<ClInclude Include="objects\currency_object.h" />
|
||||
<ClInclude Include="objects\dock_object.h" />
|
||||
<ClInclude Include="objects\industry_object.h" />
|
||||
<ClInclude Include="objects\interface_skin_object.h" />
|
||||
<ClInclude Include="objects\land_object.h" />
|
||||
|
@ -191,6 +197,8 @@
|
|||
<ClInclude Include="objects\steam_object.h" />
|
||||
<ClInclude Include="objects\track_extra_object.h" />
|
||||
<ClInclude Include="objects\track_object.h" />
|
||||
<ClInclude Include="objects\train_signal_object.h" />
|
||||
<ClInclude Include="objects\train_station_object.h" />
|
||||
<ClInclude Include="objects\tree_object.h" />
|
||||
<ClInclude Include="objects\vehicle_object.h" />
|
||||
<ClInclude Include="objects\wall_object.h" />
|
||||
|
@ -230,6 +238,7 @@
|
|||
<ClInclude Include="widget.h" />
|
||||
<ClInclude Include="win32.h" />
|
||||
<ClInclude Include="window.h" />
|
||||
<ClInclude Include="windows\construction\Construction.h" />
|
||||
<ClInclude Include="windows\toolbar_top_common.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -77,7 +77,10 @@ namespace openloco
|
|||
town_id_t town; // 0x2C
|
||||
station_cargo_stats cargo_stats[max_cargo_stats]; // 0x2E
|
||||
uint16_t var_1CE;
|
||||
uint8_t pad_1D0[0x3B0 - 0x1D0];
|
||||
uint16_t var_1D0;
|
||||
uint16_t var_1D2;
|
||||
uint16_t var_1D4;
|
||||
uint8_t pad_1D6[0x3B0 - 0x1D6];
|
||||
uint8_t var_3B0;
|
||||
uint8_t var_3B1;
|
||||
uint8_t pad_3B2[0x3D2 - 0x3B2];
|
||||
|
|
|
@ -1836,6 +1836,104 @@ namespace openloco::ui::WindowManager
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 0x004A0A18
|
||||
*
|
||||
* @param visibility @<al>
|
||||
*/
|
||||
void viewportSetVisibility(viewport_visibility visibility)
|
||||
{
|
||||
auto window = WindowManager::getMainWindow();
|
||||
|
||||
if (window == nullptr)
|
||||
return;
|
||||
|
||||
auto viewport = window->viewports[0];
|
||||
bool flagsChanged = false;
|
||||
|
||||
switch (visibility)
|
||||
{
|
||||
case viewport_visibility::undergroundView:
|
||||
{
|
||||
if (!(viewport->flags & (viewport_flags::underground_view)))
|
||||
{
|
||||
viewport->flags |= (viewport_flags::underground_view);
|
||||
flagsChanged = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case viewport_visibility::heightMarksOnLand:
|
||||
{
|
||||
if (!(viewport->flags & (viewport_flags::height_marks_on_land)))
|
||||
{
|
||||
viewport->flags |= (viewport_flags::height_marks_on_land);
|
||||
flagsChanged = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case viewport_visibility::overgroundView:
|
||||
{
|
||||
if ((viewport->flags & (viewport_flags::underground_view)))
|
||||
{
|
||||
viewport->flags &= ~(viewport_flags::underground_view);
|
||||
flagsChanged = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if (viewport->flags & (viewport_flags::underground_view))
|
||||
{
|
||||
viewport->flags &= ~(viewport_flags::underground_view);
|
||||
flagsChanged = true;
|
||||
}
|
||||
|
||||
if (viewport->flags & (viewport_flags::flag_7))
|
||||
{
|
||||
viewport->flags &= ~(viewport_flags::flag_7);
|
||||
flagsChanged = true;
|
||||
}
|
||||
|
||||
if (viewport->flags & (viewport_flags::flag_8))
|
||||
{
|
||||
viewport->flags &= ~(viewport_flags::flag_8);
|
||||
flagsChanged = true;
|
||||
}
|
||||
|
||||
if (viewport->flags & (viewport_flags::hide_foreground_tracks_roads))
|
||||
{
|
||||
viewport->flags &= ~(viewport_flags::hide_foreground_tracks_roads);
|
||||
flagsChanged = true;
|
||||
}
|
||||
|
||||
if (viewport->flags & (viewport_flags::hide_foreground_scenery_buildings))
|
||||
{
|
||||
viewport->flags &= ~(viewport_flags::hide_foreground_scenery_buildings);
|
||||
flagsChanged = true;
|
||||
}
|
||||
|
||||
if (viewport->flags & (viewport_flags::height_marks_on_land))
|
||||
{
|
||||
viewport->flags &= ~(viewport_flags::height_marks_on_land);
|
||||
flagsChanged = true;
|
||||
}
|
||||
|
||||
if (viewport->flags & (viewport_flags::height_marks_on_tracks_roads))
|
||||
{
|
||||
viewport->flags &= ~(viewport_flags::height_marks_on_tracks_roads);
|
||||
flagsChanged = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (flagsChanged)
|
||||
window->invalidate();
|
||||
}
|
||||
|
||||
// 0x004CF456
|
||||
void closeAllFloatingWindows()
|
||||
{
|
||||
|
@ -1871,7 +1969,8 @@ namespace openloco::ui::WindowManager
|
|||
namespace openloco::ui::windows
|
||||
{
|
||||
static loco_global<uint8_t, 0x00508F09> suppressErrorSound;
|
||||
static loco_global<int8_t, 0x00F2533F> _gridlines_state;
|
||||
static loco_global<int8_t, 0x00F2533F> _gridlinesState;
|
||||
static loco_global<uint8_t, 0x0112C2E1> _directionArrowsState;
|
||||
|
||||
// 0x00431A8A
|
||||
void show_error(string_id title, string_id message, bool sound)
|
||||
|
@ -1889,7 +1988,7 @@ namespace openloco::ui::windows
|
|||
// 0x00468FD3
|
||||
void showGridlines()
|
||||
{
|
||||
if (!_gridlines_state)
|
||||
if (!_gridlinesState)
|
||||
{
|
||||
auto window = WindowManager::getMainWindow();
|
||||
if (window != nullptr)
|
||||
|
@ -1901,14 +2000,14 @@ namespace openloco::ui::windows
|
|||
window->viewports[0]->flags |= viewport_flags::gridlines_on_landscape;
|
||||
}
|
||||
}
|
||||
_gridlines_state++;
|
||||
_gridlinesState++;
|
||||
}
|
||||
|
||||
// 0x00468FFE
|
||||
void hideGridlines()
|
||||
{
|
||||
_gridlines_state--;
|
||||
if (!_gridlines_state)
|
||||
_gridlinesState--;
|
||||
if (!_gridlinesState)
|
||||
{
|
||||
if (!(config::get().flags & config::flags::gridlines_on_landscape))
|
||||
{
|
||||
|
@ -1919,7 +2018,43 @@ namespace openloco::ui::windows
|
|||
{
|
||||
window->invalidate();
|
||||
}
|
||||
window->viewports[0]->flags ^= viewport_flags::gridlines_on_landscape;
|
||||
window->viewports[0]->flags &= ~viewport_flags::gridlines_on_landscape;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0x004793C4
|
||||
void showDirectionArrows()
|
||||
{
|
||||
if (!_directionArrowsState)
|
||||
{
|
||||
auto mainWindow = WindowManager::getMainWindow();
|
||||
if (mainWindow != nullptr)
|
||||
{
|
||||
if (!(mainWindow->viewports[0]->flags & viewport_flags::one_way_direction_arrows))
|
||||
{
|
||||
mainWindow->viewports[0]->flags |= viewport_flags::one_way_direction_arrows;
|
||||
mainWindow->invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
_directionArrowsState++;
|
||||
}
|
||||
|
||||
// 0x004793EF
|
||||
void hideDirectionArrows()
|
||||
{
|
||||
_directionArrowsState--;
|
||||
if (!_directionArrowsState)
|
||||
{
|
||||
auto mainWindow = WindowManager::getMainWindow();
|
||||
if (mainWindow != nullptr)
|
||||
{
|
||||
if ((mainWindow->viewports[0]->flags & viewport_flags::one_way_direction_arrows))
|
||||
{
|
||||
mainWindow->viewports[0]->flags &= ~viewport_flags::one_way_direction_arrows;
|
||||
mainWindow->invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,14 @@
|
|||
|
||||
namespace openloco::ui::WindowManager
|
||||
{
|
||||
enum class viewport_visibility
|
||||
{
|
||||
reset,
|
||||
undergroundView,
|
||||
heightMarksOnLand,
|
||||
overgroundView,
|
||||
};
|
||||
|
||||
void init();
|
||||
void registerHooks();
|
||||
WindowType getCurrentModalType();
|
||||
|
@ -55,6 +63,7 @@ namespace openloco::ui::WindowManager
|
|||
int32_t getCurrentRotation();
|
||||
|
||||
void viewport_shift_pixels(ui::window* window, ui::viewport* viewport, int16_t dX, int16_t dY);
|
||||
void viewportSetVisibility(viewport_visibility flags);
|
||||
}
|
||||
|
||||
namespace openloco::ui::windows
|
||||
|
@ -73,6 +82,8 @@ namespace openloco::ui::windows
|
|||
|
||||
void showGridlines();
|
||||
void hideGridlines();
|
||||
void showDirectionArrows();
|
||||
void hideDirectionArrows();
|
||||
}
|
||||
|
||||
namespace openloco::ui::about
|
||||
|
@ -98,7 +109,8 @@ namespace openloco::ui::about_music
|
|||
namespace openloco::ui::windows::construction
|
||||
{
|
||||
window* openWithFlags(uint32_t flags);
|
||||
void on_mouse_up(window& w, uint16_t widgetIndex);
|
||||
void sub_4A6FAC();
|
||||
void registerHooks();
|
||||
}
|
||||
|
||||
namespace openloco::ui::windows::industry
|
||||
|
@ -165,6 +177,7 @@ namespace openloco::ui::windows::ScenarioOptions
|
|||
namespace openloco::ui::windows::station
|
||||
{
|
||||
window* open(uint16_t id);
|
||||
void showStationCatchment(uint16_t windowNumber);
|
||||
}
|
||||
|
||||
namespace openloco::ui::windows::station_list
|
||||
|
|
|
@ -150,6 +150,23 @@ namespace openloco::ui::dropdown
|
|||
call(0x004CC807, regs);
|
||||
}
|
||||
|
||||
// Custom dropdown height if flags & (1<<6) is true
|
||||
void show(int16_t x, int16_t y, int16_t width, int16_t height, colour_t colour, size_t count, uint8_t itemHeight, uint8_t flags)
|
||||
{
|
||||
assert(count < std::numeric_limits<uint8_t>::max());
|
||||
registers regs;
|
||||
regs.cx = x;
|
||||
regs.dx = y;
|
||||
regs.al = colour;
|
||||
regs.ah = itemHeight;
|
||||
regs.bl = static_cast<uint8_t>(count);
|
||||
regs.bh = flags;
|
||||
regs.bp = width;
|
||||
regs.di = height;
|
||||
|
||||
call(0x004CC807, regs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 0x004CCDE7
|
||||
*
|
||||
|
|
|
@ -64,6 +64,7 @@ namespace openloco::ui::dropdown
|
|||
void set_item_selected(size_t index);
|
||||
|
||||
void show(int16_t x, int16_t y, int16_t width, int16_t height, colour_t colour, size_t count, uint8_t flags);
|
||||
void show(int16_t x, int16_t y, int16_t width, int16_t height, colour_t colour, size_t count, uint8_t itemHeight, uint8_t flags);
|
||||
void show_image(int16_t x, int16_t y, int16_t width, int16_t height, int16_t heightOffset, colour_t colour, uint8_t columnCount, uint8_t count);
|
||||
void show_below(window* window, widget_index widgetIndex, size_t count);
|
||||
void show_below(window* window, widget_index widgetIndex, size_t count, int8_t height);
|
||||
|
@ -72,7 +73,6 @@ namespace openloco::ui::dropdown
|
|||
|
||||
void populateCompanySelect(window* window, widget_t* widget);
|
||||
company_id_t getCompanyIdFromSelection(int16_t itemIndex);
|
||||
void populateTownSizeSelect(window* window, widget_t* widget);
|
||||
uint16_t getItemArgument(const uint8_t index, const uint8_t argument);
|
||||
uint16_t getItemsPerRow(uint8_t itemCount);
|
||||
}
|
||||
|
|
|
@ -436,7 +436,7 @@ namespace openloco::ui::build_vehicle
|
|||
for (uint16_t vehicleObjIndex = 0; vehicleObjIndex < objectmgr::get_max_objects(object_type::vehicle); ++vehicleObjIndex)
|
||||
{
|
||||
auto vehicleObj = objectmgr::get<vehicle_object>(vehicleObjIndex);
|
||||
if ((uint32_t)vehicleObj == 0xFFFFFFFF)
|
||||
if (vehicleObj == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,391 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../interop/interop.hpp"
|
||||
#include "../../map/tilemgr.h"
|
||||
#include "../../objects/vehicle_object.h"
|
||||
#include "../../ui/WindowManager.h"
|
||||
|
||||
using namespace openloco::interop;
|
||||
using namespace openloco::map;
|
||||
using namespace openloco::map::tilemgr;
|
||||
|
||||
namespace openloco::ui::windows::construction
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
struct previewTrack
|
||||
{
|
||||
uint8_t index; // 0x00
|
||||
int16_t x; // 0x01
|
||||
int16_t y; // 0x03
|
||||
int16_t z; // 0x05
|
||||
uint8_t var_07;
|
||||
uint8_t var_08;
|
||||
uint8_t flags; // 0x09
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
enum previewTrackFlags
|
||||
{
|
||||
diagonal = 1 << 7,
|
||||
};
|
||||
|
||||
static loco_global<int32_t, 0x00E3F0B8> gCurrentRotation;
|
||||
static loco_global<previewTrack[1], 0x004F6D44> _unk_4F6D44;
|
||||
static loco_global<previewTrack[1], 0x004F6D4F> _unk_4F6D4F;
|
||||
static loco_global<previewTrack[1], 0x004F6D5A> _unk_4F6D5A;
|
||||
static loco_global<previewTrack[4], 0x004F6D65> _unk_4F6D65;
|
||||
static loco_global<previewTrack[4], 0x004F6D8E> _unk_4F6D8E;
|
||||
static loco_global<previewTrack[2], 0x004F6DB7> _unk_4F6DB7;
|
||||
static loco_global<previewTrack[2], 0x004F6DCC> _unk_4F6DCC;
|
||||
static loco_global<previewTrack[1], 0x004F6DE1> _unk_4F6DE1;
|
||||
static loco_global<previewTrack[1], 0x004F6DEC> _unk_4F6DEC;
|
||||
static loco_global<previewTrack[1], 0x004F6DF7> _unk_4F6DF7;
|
||||
|
||||
static loco_global<previewTrack[1], 0x004F7488> _unk_4F7488;
|
||||
static loco_global<previewTrack[4], 0x004F7493> _unk_4F7493;
|
||||
static loco_global<previewTrack[1], 0x004F74BC> _unk_4F74BC;
|
||||
static loco_global<previewTrack[1], 0x004F74C7> _unk_4F74C7;
|
||||
static loco_global<previewTrack[4], 0x004F74D2> _unk_4F74D2;
|
||||
static loco_global<previewTrack[4], 0x004F74FB> _unk_4F74FB;
|
||||
static loco_global<previewTrack[5], 0x004F7524> _unk_4F7524;
|
||||
static loco_global<previewTrack[5], 0x004F7557> _unk_4F7557;
|
||||
static loco_global<previewTrack[5], 0x004F758A> _unk_4F758A;
|
||||
static loco_global<previewTrack[5], 0x004F75BD> _unk_4F75BD;
|
||||
static loco_global<previewTrack[5], 0x004F75F0> _unk_4F75F0;
|
||||
static loco_global<previewTrack[5], 0x004F7623> _unk_4F7623;
|
||||
static loco_global<previewTrack[4], 0x004F7656> _unk_4F7656;
|
||||
static loco_global<previewTrack[4], 0x004F767F> _unk_4F767F;
|
||||
static loco_global<previewTrack[2], 0x004F76A8> _unk_4F76A8;
|
||||
static loco_global<previewTrack[2], 0x004F76BD> _unk_4F76BD;
|
||||
static loco_global<previewTrack[1], 0x004F76D2> _unk_4F76D2;
|
||||
static loco_global<previewTrack[1], 0x004F76DD> _unk_4F76DD;
|
||||
static loco_global<previewTrack[4], 0x004F76E8> _unk_4F76E8;
|
||||
static loco_global<previewTrack[4], 0x004F7711> _unk_4F7711;
|
||||
static loco_global<previewTrack[4], 0x004F773A> _unk_4F773A;
|
||||
static loco_global<previewTrack[4], 0x004F7763> _unk_4F7763;
|
||||
static loco_global<previewTrack[4], 0x004F778C> _unk_4F778C;
|
||||
static loco_global<previewTrack[4], 0x004F77B5> _unk_4F77B5;
|
||||
static loco_global<previewTrack[4], 0x004F77DE> _unk_4F77DE;
|
||||
static loco_global<previewTrack[4], 0x004F7807> _unk_4F7807;
|
||||
static loco_global<previewTrack[1], 0x004F7830> _unk_4F7830;
|
||||
static loco_global<previewTrack[1], 0x004F783B> _unk_4F783B;
|
||||
static loco_global<previewTrack[1], 0x004F7846> _unk_4F7846;
|
||||
static loco_global<previewTrack[1], 0x004F7851> _unk_4F7851;
|
||||
static loco_global<previewTrack[1], 0x004F785C> _unk_4F785C;
|
||||
static loco_global<previewTrack[1], 0x004F7867> _unk_4F7867;
|
||||
static loco_global<previewTrack[1], 0x004F7872> _unk_4F7872;
|
||||
static loco_global<previewTrack[1], 0x004F787D> _unk_4F787D;
|
||||
static loco_global<previewTrack[1], 0x004F7888> _unk_4F7888;
|
||||
static loco_global<previewTrack[1], 0x004F7893> _unk_4F7893;
|
||||
static loco_global<previewTrack[1], 0x004F789E> _unk_4F789E;
|
||||
static loco_global<previewTrack[1], 0x004F78A9> _unk_4F78A9;
|
||||
static loco_global<previewTrack[1], 0x004F78B4> _unk_4F78B4;
|
||||
static loco_global<previewTrack[1], 0x004F78BF> _unk_4F78BF;
|
||||
static loco_global<previewTrack[1], 0x004F78CA> _unk_4F78CA;
|
||||
static loco_global<previewTrack[1], 0x004F78D5> _unk_4F78D5;
|
||||
static loco_global<previewTrack[1], 0x004F78E0> _unk_4F78E0;
|
||||
static loco_global<previewTrack[1], 0x004F78EB> _unk_4F78EB;
|
||||
|
||||
static loco_global<uint16_t[351][4], 0x004F7B62> _word_4F7B62; // TODO: Not sure on size?
|
||||
static loco_global<uint8_t[31], 0x005045FA> _byte_5045FA;
|
||||
static loco_global<uint8_t, 0x00508F09> _byte_508F09;
|
||||
static loco_global<uint8_t, 0x00522090> _byte_522090;
|
||||
static loco_global<uint8_t, 0x00522091> _byte_522091;
|
||||
static loco_global<uint8_t, 0x00522092> _byte_522092;
|
||||
static loco_global<uint8_t, 0x00522095> _byte_522095;
|
||||
static loco_global<uint8_t, 0x00522096> _byte_522096;
|
||||
static loco_global<uint16_t, 0x0052338A> _tooltipTimeout;
|
||||
static loco_global<ui::window_number, 0x00523390> _toolWindowNumber;
|
||||
static loco_global<ui::WindowType, 0x00523392> _toolWindowType;
|
||||
static loco_global<uint32_t, 0x00523394> _toolWidgetIndex;
|
||||
static loco_global<company_id_t, 0x00525E3C> _playerCompany;
|
||||
static loco_global<uint8_t[8], 0x0525F72> _scenarioSignals;
|
||||
static loco_global<uint8_t[8], 0x0525F7A> _scenarioBridges;
|
||||
static loco_global<uint8_t[8], 0x0525F82> _scenarioTrainStations;
|
||||
static loco_global<uint8_t[8], 0x0525F8A> _scenarioTrackMods;
|
||||
static loco_global<uint8_t[8], 0x0525F9A> _scenarioRoadStations;
|
||||
static loco_global<uint8_t[8], 0x0525FA2> _scenarioRoadMods;
|
||||
static loco_global<uint8_t, 0x00525FAA> _lastRailroadOption;
|
||||
static loco_global<uint8_t, 0x00525FAB> _lastRoadOption;
|
||||
static loco_global<uint8_t, 0x00525FAC> _lastAirport;
|
||||
static loco_global<uint8_t, 0x00525FAD> _lastShipPort;
|
||||
static loco_global<uint8_t, 0x00525FAE> _byte_525FAE;
|
||||
static loco_global<uint8_t, 0x00F24948> _byte_F24948;
|
||||
static loco_global<uint16_t, 0x00F24942> _word_F24942;
|
||||
static loco_global<uint16_t, 0x00F24944> _word_F24944;
|
||||
static loco_global<uint16_t, 0x00F24946> _word_F24946;
|
||||
static loco_global<company_id_t, 0x009C68EB> _updatingCompanyId;
|
||||
static loco_global<gfx::drawpixelinfo_t*, 0x00E0C3E0> _dword_E0C3E0;
|
||||
static loco_global<uint16_t, 0x00F24484> _mapSelectionFlags;
|
||||
constexpr uint16_t mapSelectedTilesSize = 300;
|
||||
static loco_global<map_pos[mapSelectedTilesSize], 0x00F24490> _mapSelectedTiles;
|
||||
static loco_global<string_id, 0x009C68E6> gGameCommandErrorText;
|
||||
static loco_global<int32_t, 0x112C876> _currentFontSpriteBase;
|
||||
static loco_global<char[512], 0x0112CC04> _stringFormatBuffer;
|
||||
static loco_global<uint32_t, 0x01135F3E> _trackCost;
|
||||
static loco_global<uint32_t, 0x01135F42> _dword_1135F42;
|
||||
static loco_global<uint32_t, 0x01135F46> _modCost;
|
||||
static loco_global<uint32_t, 0x01135F4E> _signalCost;
|
||||
static loco_global<uint32_t, 0x01135F6C> _stationCost;
|
||||
static loco_global<uint32_t, 0x01135F70> _constructingStationId;
|
||||
static loco_global<uint32_t, 0x01135F74> _constructingStationAcceptedCargoTypes;
|
||||
static loco_global<uint32_t, 0x01135F78> _constructingStationProducedCargoTypes;
|
||||
static loco_global<uint16_t, 0x01135F86> _word_1135F86;
|
||||
static loco_global<uint16_t, 0x01135FB4> _x;
|
||||
static loco_global<uint16_t, 0x01135FB6> _y;
|
||||
static loco_global<uint16_t, 0x01135FB8> _word_1135FB8;
|
||||
static loco_global<uint16_t, 0x01135FBA> _word_1135FBA;
|
||||
static loco_global<uint16_t, 0x01135FBC> _word_1135FBC;
|
||||
static loco_global<uint16_t, 0x01135FBE> _word_1135FBE;
|
||||
static loco_global<uint16_t, 0x01135FD6> _word_1135FD6;
|
||||
static loco_global<uint16_t, 0x01135FD8> _word_1135FD8;
|
||||
static loco_global<uint16_t, 0x01135FE4> _lastSelectedMods;
|
||||
static loco_global<uint16_t, 0x01135FFE> _word_1135FFE;
|
||||
static loco_global<uint16_t, 0x01136000> _word_1136000;
|
||||
static loco_global<uint8_t[17], 0x0113601D> _signalList;
|
||||
static loco_global<uint8_t, 0x0113602E> _lastSelectedSignal;
|
||||
static loco_global<uint8_t, 0x0113602F> _isSignalBothDirections;
|
||||
static loco_global<uint8_t[9], 0x01136030> _bridgeList;
|
||||
static loco_global<uint8_t, 0x01136039> _lastSelectedBridge;
|
||||
static loco_global<uint8_t, 0x0113603A> _byte_113603A;
|
||||
static loco_global<uint8_t[17], 0x0113603B> _stationList;
|
||||
static loco_global<uint8_t, 0x0113604C> _lastSelectedStationType;
|
||||
static loco_global<uint8_t[4], 0x01136054> _modList;
|
||||
static loco_global<uint8_t, 0x0113605D> _byte_113605D;
|
||||
static loco_global<uint8_t, 0x01136061> _constructionHover;
|
||||
static loco_global<uint8_t, 0x01136062> _trackType;
|
||||
static loco_global<uint8_t, 0x01136063> _byte_1136063;
|
||||
static loco_global<uint8_t, 0x01136064> _constructionRotation;
|
||||
static loco_global<uint8_t, 0x01136065> _byte_1136065;
|
||||
static loco_global<uint8_t, 0x01136066> _byte_1136066;
|
||||
static loco_global<uint8_t, 0x01136067> _lastSelectedTrackPiece;
|
||||
static loco_global<uint8_t, 0x01136068> _lastSelectedTrackGradient;
|
||||
static loco_global<uint8_t, 0x0113606E> _lastSelectedTrackModSection;
|
||||
static loco_global<uint8_t, 0x01136073> _byte_1136073;
|
||||
static loco_global<uint8_t, 0x01136075> _byte_1136075;
|
||||
static loco_global<uint8_t, 0x01136076> _byte_1136076;
|
||||
static loco_global<uint8_t, 0x01136077> _byte_1136077;
|
||||
static loco_global<uint8_t, 0x01136078> _byte_1136078;
|
||||
static loco_global<uint8_t, 0x01136079> _lastSelectedTrackPieceId;
|
||||
static loco_global<uint8_t, 0x0113607E> _byte_113607E;
|
||||
|
||||
namespace common
|
||||
{
|
||||
enum widx
|
||||
{
|
||||
frame,
|
||||
caption,
|
||||
close_button,
|
||||
panel,
|
||||
tab_construction,
|
||||
tab_station,
|
||||
tab_signal,
|
||||
tab_overhead,
|
||||
};
|
||||
|
||||
enum trackPiece
|
||||
{
|
||||
straight,
|
||||
left_hand_curve_very_small,
|
||||
right_hand_curve_very_small,
|
||||
left_hand_curve_small,
|
||||
right_hand_curve_small,
|
||||
left_hand_curve,
|
||||
right_hand_curve,
|
||||
left_hand_curve_large,
|
||||
right_hand_curve_large,
|
||||
s_bend_left,
|
||||
s_bend_right,
|
||||
s_bend_to_dual_track,
|
||||
s_bend_to_single_track,
|
||||
turnaround,
|
||||
};
|
||||
|
||||
enum trackGradient
|
||||
{
|
||||
level = 0,
|
||||
slope_up = 2,
|
||||
steep_slope_up = 4,
|
||||
slope_down = 6,
|
||||
steep_slope_down = 8,
|
||||
};
|
||||
|
||||
struct trackPieceId
|
||||
{
|
||||
uint8_t id;
|
||||
uint8_t rotation;
|
||||
};
|
||||
|
||||
#define commonWidgets(frameWidth, frameHeight, windowCaptionId) \
|
||||
make_widget({ 0, 0 }, { frameWidth, frameHeight }, widget_type::frame, 0), \
|
||||
make_widget({ 1, 1 }, { frameWidth - 2, 13 }, widget_type::caption_24, 0, windowCaptionId), \
|
||||
make_widget({ frameWidth - 15, 2 }, { 13, 13 }, widget_type::wt_9, 0, image_ids::close_button, string_ids::tooltip_close_window), \
|
||||
make_widget({ 0, 41 }, { frameWidth, 235 }, widget_type::wt_3, 1), \
|
||||
make_remap_widget({ 3, 15 }, { 31, 27 }, widget_type::wt_8, 1, image_ids::tab, string_ids::tab_track_road_construction), \
|
||||
make_remap_widget({ 34, 15 }, { 31, 27 }, widget_type::wt_8, 1, image_ids::tab, string_ids::tab_station_construction), \
|
||||
make_remap_widget({ 65, 15 }, { 31, 27 }, widget_type::wt_8, 1, image_ids::tab, string_ids::tab_signal_construction), \
|
||||
make_remap_widget({ 96, 15 }, { 31, 27 }, widget_type::wt_8, 1, image_ids::tab, string_ids::tab_electrification_construction)
|
||||
|
||||
constexpr uint64_t enabledWidgets = (1 << widx::caption) | (1 << widx::close_button) | (1 << widx::tab_construction) | (1 << widx::tab_station) | (1 << widx::tab_signal) | (1 << widx::tab_overhead);
|
||||
|
||||
void prepare_draw(window* self);
|
||||
void switchTab(window* self, widget_index widgetIndex);
|
||||
void repositionTabs(window* self);
|
||||
void drawTabs(window* self, gfx::drawpixelinfo_t* dpi);
|
||||
void init_events();
|
||||
std::optional<trackPieceId> getRoadPieceId(uint8_t trackPiece, uint8_t gradient, uint8_t rotation);
|
||||
std::optional<trackPieceId> getTrackPieceId(uint8_t trackPiece, uint8_t gradient, uint8_t rotation);
|
||||
void activateSelectedConstructionWidgets();
|
||||
void sub_49FEC7();
|
||||
void on_close(window* self);
|
||||
void on_update(window* self, uint8_t flag);
|
||||
void sub_4CD454();
|
||||
void setTrackOptions(const uint8_t trackType);
|
||||
void setDisabledWidgets(window* self);
|
||||
void createConstructionWindow();
|
||||
void refreshAirportList(uint8_t* stationList);
|
||||
void refreshDockList(uint8_t* stationList);
|
||||
void refreshStationList(uint8_t* stationList, uint8_t trackType, TransportMode transportMode);
|
||||
void refreshBridgeList(uint8_t* bridgeList, uint8_t trackType, TransportMode transportMode);
|
||||
void refreshModList(uint8_t* modList, uint8_t trackType, TransportMode transportMode);
|
||||
void sub_4A3A50();
|
||||
void refreshSignalList(uint8_t* signalList, uint8_t trackType);
|
||||
|
||||
extern const uint8_t trackPieceWidgets[11];
|
||||
extern const previewTrack* roadPieces[10];
|
||||
extern const previewTrack* trackPieces[44];
|
||||
}
|
||||
|
||||
namespace construction
|
||||
{
|
||||
static const gfx::ui_size_t windowSize = { 138, 276 };
|
||||
|
||||
enum widx
|
||||
{
|
||||
left_hand_curve_very_small = 8,
|
||||
left_hand_curve_small,
|
||||
left_hand_curve,
|
||||
left_hand_curve_large,
|
||||
right_hand_curve_large,
|
||||
right_hand_curve,
|
||||
right_hand_curve_small,
|
||||
right_hand_curve_very_small,
|
||||
s_bend_dual_track_left,
|
||||
s_bend_left,
|
||||
straight,
|
||||
s_bend_right,
|
||||
s_bend_dual_track_right,
|
||||
steep_slope_down,
|
||||
slope_down,
|
||||
level,
|
||||
slope_up,
|
||||
steep_slope_up,
|
||||
bridge,
|
||||
bridge_dropdown,
|
||||
construct,
|
||||
remove,
|
||||
rotate_90,
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
constexpr uint64_t allTrack = {
|
||||
(1ULL << widx::left_hand_curve_very_small) |
|
||||
(1ULL << widx::left_hand_curve_small) |
|
||||
(1ULL << widx::left_hand_curve) |
|
||||
(1ULL << widx::left_hand_curve_large) |
|
||||
(1ULL << widx::right_hand_curve_large) |
|
||||
(1ULL << widx::right_hand_curve) |
|
||||
(1ULL << widx::right_hand_curve_small) |
|
||||
(1ULL << widx::right_hand_curve_very_small ) |
|
||||
(1ULL << widx::s_bend_dual_track_left) |
|
||||
(1ULL << widx::s_bend_left) |
|
||||
(1ULL << widx::straight) |
|
||||
(1ULL << widx::s_bend_right) |
|
||||
(1ULL << widx::s_bend_dual_track_right) |
|
||||
(1ULL << widx::steep_slope_down) |
|
||||
(1ULL << widx::slope_down) |
|
||||
(1ULL << widx::level) |
|
||||
(1ULL << widx::slope_up) |
|
||||
(1ULL << widx::steep_slope_up)
|
||||
};
|
||||
|
||||
constexpr uint64_t allConstruction = {
|
||||
allTrack |
|
||||
(1ULL << widx::bridge) |
|
||||
(1ULL << widx::bridge_dropdown) |
|
||||
(1ULL << widx::construct) |
|
||||
(1ULL << widx::remove) |
|
||||
(1ULL << widx::rotate_90)
|
||||
};
|
||||
//clang-format on
|
||||
|
||||
extern widget_t widgets[32];
|
||||
|
||||
extern window_event_list events;
|
||||
constexpr uint64_t enabledWidgets = common::enabledWidgets | allConstruction;
|
||||
void tabReset(window* self);
|
||||
void init_events();
|
||||
void drawTrack(uint16_t x, uint16_t y, uint16_t selectedMods, uint16_t di, uint8_t trackType, uint8_t trackPieceId, uint16_t colour, uint8_t bh);
|
||||
void drawRoad(uint16_t x, uint16_t y, uint16_t selectedMods, uint16_t di, uint8_t trackType, uint8_t trackPieceId, uint16_t colour, uint8_t bh);
|
||||
}
|
||||
|
||||
namespace station
|
||||
{
|
||||
enum widx
|
||||
{
|
||||
station = 8,
|
||||
station_dropdown,
|
||||
image,
|
||||
rotate,
|
||||
};
|
||||
|
||||
extern widget_t widgets[13];
|
||||
|
||||
const uint64_t enabledWidgets = common::enabledWidgets | (1 << station) | (1 << station_dropdown) | (1 << image) | (1 << rotate);
|
||||
|
||||
extern window_event_list events;
|
||||
void tabReset(window* self);
|
||||
void init_events();
|
||||
}
|
||||
|
||||
namespace signal
|
||||
{
|
||||
enum widx
|
||||
{
|
||||
signal = 8,
|
||||
signal_dropdown,
|
||||
both_directions,
|
||||
single_direction,
|
||||
};
|
||||
|
||||
extern widget_t widgets[13];
|
||||
|
||||
const uint64_t enabledWidgets = common::enabledWidgets | (1 << signal) | (1 << signal_dropdown) | (1 << both_directions) | (1 << single_direction);
|
||||
|
||||
extern window_event_list events;
|
||||
void tabReset(window* self);
|
||||
void init_events();
|
||||
}
|
||||
|
||||
namespace overhead
|
||||
{
|
||||
enum widx
|
||||
{
|
||||
checkbox_1 = 8,
|
||||
checkbox_2,
|
||||
checkbox_3,
|
||||
checkbox_4,
|
||||
image,
|
||||
track,
|
||||
track_dropdown,
|
||||
};
|
||||
|
||||
extern widget_t widgets[16];
|
||||
|
||||
const uint64_t enabledWidgets = common::enabledWidgets | (1 << checkbox_1) | (1 << checkbox_2) | (1 << checkbox_3) | (1 << checkbox_4) | (1 << image) | (1 << track) | (1 << track_dropdown);
|
||||
|
||||
extern window_event_list events;
|
||||
void tabReset(window* self);
|
||||
void init_events();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,309 @@
|
|||
#include "../../companymgr.h"
|
||||
#include "../../graphics/image_ids.h"
|
||||
#include "../../input.h"
|
||||
#include "../../localisation/FormatArguments.hpp"
|
||||
#include "../../objects/objectmgr.h"
|
||||
#include "../../objects/road_extra_object.h"
|
||||
#include "../../objects/road_object.h"
|
||||
#include "../../objects/track_extra_object.h"
|
||||
#include "../../objects/track_object.h"
|
||||
#include "../../ui/dropdown.h"
|
||||
#include "Construction.h"
|
||||
|
||||
using namespace openloco::interop;
|
||||
using namespace openloco::map;
|
||||
using namespace openloco::map::tilemgr;
|
||||
|
||||
namespace openloco::ui::windows::construction::overhead
|
||||
{
|
||||
widget_t widgets[] = {
|
||||
commonWidgets(138, 192, string_ids::stringid_2),
|
||||
make_widget({ 3, 45 }, { 132, 12 }, widget_type::checkbox, 1, string_ids::empty, string_ids::tooltip_select_track_mod),
|
||||
make_widget({ 3, 57 }, { 132, 12 }, widget_type::checkbox, 1, string_ids::empty, string_ids::tooltip_select_track_mod),
|
||||
make_widget({ 3, 69 }, { 132, 12 }, widget_type::checkbox, 1, string_ids::empty, string_ids::tooltip_select_track_mod),
|
||||
make_widget({ 3, 81 }, { 132, 12 }, widget_type::checkbox, 1, string_ids::empty, string_ids::tooltip_select_track_mod),
|
||||
make_widget({ 35, 110 }, { 66, 66 }, widget_type::wt_3, 1),
|
||||
make_widget({ 3, 95 }, { 132, 12 }, widget_type::wt_18, 1, 0xFFFFFFFF, string_ids::tooltip_select_track_to_upgrade),
|
||||
make_widget({ 123, 96 }, { 11, 10 }, widget_type::wt_11, 1, string_ids::dropdown, string_ids::tooltip_select_track_to_upgrade),
|
||||
widget_end(),
|
||||
};
|
||||
|
||||
window_event_list events;
|
||||
|
||||
// 0x0049EBD1
|
||||
static void on_mouse_up(window* self, widget_index 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 on_mouse_down(window* self, widget_index 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->colours[1], modCount, (1 << 7));
|
||||
|
||||
dropdown::add(0, string_ids::single_section);
|
||||
dropdown::add(1, string_ids::block_section);
|
||||
dropdown::add(2, string_ids::all_connected_track);
|
||||
|
||||
dropdown::set_highlighted_item(_lastSelectedTrackModSection);
|
||||
break;
|
||||
}
|
||||
|
||||
case widx::image:
|
||||
{
|
||||
input::cancel_tool();
|
||||
input::toolSet(self, widgetIndex, 12);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0x0049EC09
|
||||
static void on_dropdown(window* self, widget_index widgetIndex, int16_t itemIndex)
|
||||
{
|
||||
if (widgetIndex != widx::track_dropdown)
|
||||
return;
|
||||
|
||||
if (itemIndex != -1)
|
||||
{
|
||||
_lastSelectedTrackModSection = itemIndex;
|
||||
self->invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
// 0x0049ECD1
|
||||
static void on_update(window* self)
|
||||
{
|
||||
common::on_update(self, (1 << 5));
|
||||
}
|
||||
|
||||
// 0x0049EC15
|
||||
static void on_tool_update(window& self, const widget_index 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 on_tool_down(window& self, const widget_index 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, widget_index checkboxIndex, string_id name)
|
||||
{
|
||||
auto widgetIndex = checkboxIndex + widx::checkbox_1;
|
||||
self->widgets[widgetIndex].type = widget_type::checkbox;
|
||||
self->widgets[widgetIndex].text = name;
|
||||
|
||||
if (_lastSelectedMods & (1 << checkboxIndex))
|
||||
self->activated_widgets |= (1ULL << widgetIndex);
|
||||
}
|
||||
|
||||
// 0x0049E7D3
|
||||
static void prepare_draw(window* self)
|
||||
{
|
||||
common::prepare_draw(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 = widget_type::none;
|
||||
self->widgets[widx::checkbox_2].type = widget_type::none;
|
||||
self->widgets[widx::checkbox_3].type = widget_type::none;
|
||||
self->widgets[widx::checkbox_4].type = widget_type::none;
|
||||
|
||||
if (_trackType & (1 << 7))
|
||||
{
|
||||
auto trackType = _trackType & ~(1 << 7);
|
||||
auto roadObj = objectmgr::get<road_object>(trackType);
|
||||
|
||||
auto args = FormatArguments();
|
||||
args.push(roadObj->name);
|
||||
|
||||
for (auto i = 0; i < 2; i++)
|
||||
{
|
||||
if (_modList[i] != 0xFF)
|
||||
{
|
||||
auto extraName = objectmgr::get<road_extra_object>(_modList[i])->name;
|
||||
setCheckbox(self, i, extraName);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto trackObj = objectmgr::get<track_object>(_trackType);
|
||||
|
||||
auto args = FormatArguments();
|
||||
args.push(trackObj->name);
|
||||
|
||||
for (auto i = 0; i < 4; i++)
|
||||
{
|
||||
if (_modList[i] != 0xFF)
|
||||
{
|
||||
auto extraName = objectmgr::get<track_extra_object>(_modList[i])->name;
|
||||
setCheckbox(self, i, extraName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//self->activated_widgets = activatedWidgets;
|
||||
|
||||
self->widgets[widx::image].type = widget_type::none;
|
||||
self->widgets[widx::track].type = widget_type::none;
|
||||
self->widgets[widx::track_dropdown].type = widget_type::none;
|
||||
|
||||
self->widgets[widx::image].tooltip = string_ids::null;
|
||||
|
||||
if (_lastSelectedMods & 0xF)
|
||||
{
|
||||
self->widgets[widx::image].type = widget_type::wt_3;
|
||||
self->widgets[widx::track].type = widget_type::wt_18;
|
||||
self->widgets[widx::track_dropdown].type = widget_type::wt_11;
|
||||
|
||||
self->widgets[widx::image].tooltip = string_ids::upgrade_track_with_mods;
|
||||
|
||||
if (isTrackUpgradeMode())
|
||||
{
|
||||
if (_toolWindowType == WindowType::construction)
|
||||
self->widgets[widx::image].tooltip = string_ids::click_track_to_upgrade;
|
||||
}
|
||||
}
|
||||
|
||||
static string_id modString[] = {
|
||||
string_ids::single_section,
|
||||
string_ids::block_section,
|
||||
string_ids::all_connected_track,
|
||||
};
|
||||
|
||||
self->widgets[widx::track].text = modString[_lastSelectedTrackModSection];
|
||||
|
||||
common::repositionTabs(self);
|
||||
}
|
||||
|
||||
// 0x0049EA3E
|
||||
static void draw(window* self, gfx::drawpixelinfo_t* dpi)
|
||||
{
|
||||
self->draw(dpi);
|
||||
common::drawTabs(self, dpi);
|
||||
if (_lastSelectedMods & 0xF)
|
||||
{
|
||||
gfx::drawpixelinfo_t* 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::clip_drawpixelinfo(&clipped, dpi, 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 = companymgr::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::draw_string_centred(*dpi, xPos, yPos, colour::black, string_ids::build_cost, &args);
|
||||
}
|
||||
}
|
||||
|
||||
void tabReset(window* self)
|
||||
{
|
||||
self->call_on_mouse_down(overhead::widx::image);
|
||||
}
|
||||
|
||||
void init_events()
|
||||
{
|
||||
events.on_close = common::on_close;
|
||||
events.on_mouse_up = on_mouse_up;
|
||||
events.on_mouse_down = on_mouse_down;
|
||||
events.on_dropdown = on_dropdown;
|
||||
events.on_update = on_update;
|
||||
events.on_tool_update = on_tool_update;
|
||||
events.on_tool_down = on_tool_down;
|
||||
events.prepare_draw = prepare_draw;
|
||||
events.draw = draw;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
#include "../../graphics/image_ids.h"
|
||||
#include "../../input.h"
|
||||
#include "../../localisation/FormatArguments.hpp"
|
||||
#include "../../objects/objectmgr.h"
|
||||
#include "../../objects/track_object.h"
|
||||
#include "../../objects/train_signal_object.h"
|
||||
#include "../../ui/dropdown.h"
|
||||
#include "Construction.h"
|
||||
|
||||
using namespace openloco::interop;
|
||||
using namespace openloco::map;
|
||||
using namespace openloco::map::tilemgr;
|
||||
|
||||
namespace openloco::ui::windows::construction::signal
|
||||
{
|
||||
widget_t widgets[] = {
|
||||
commonWidgets(138, 167, string_ids::stringid_2),
|
||||
make_widget({ 3, 45 }, { 132, 12 }, widget_type::wt_18, 1, 0xFFFFFFFF, string_ids::tooltip_select_signal_type),
|
||||
make_widget({ 123, 46 }, { 11, 10 }, widget_type::wt_11, 1, string_ids::dropdown, string_ids::tooltip_select_signal_type),
|
||||
make_widget({ 27, 110 }, { 40, 40 }, widget_type::wt_9, 1, 0xFFFFFFFF, string_ids::tooltip_signal_both_directions),
|
||||
make_widget({ 71, 110 }, { 40, 40 }, widget_type::wt_9, 1, 0xFFFFFFFF, string_ids::tooltip_signal_single_direction),
|
||||
widget_end(),
|
||||
};
|
||||
|
||||
window_event_list events;
|
||||
|
||||
// 0x0049E64E
|
||||
static void on_mouse_up(window* self, widget_index 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;
|
||||
}
|
||||
}
|
||||
|
||||
// 0x0049E669
|
||||
static void on_mouse_down(window* self, widget_index widgetIndex)
|
||||
{
|
||||
switch (widgetIndex)
|
||||
{
|
||||
case widx::signal_dropdown:
|
||||
{
|
||||
uint8_t signalCount = 0;
|
||||
while (_signalList[signalCount] != 0xFF)
|
||||
signalCount++;
|
||||
|
||||
auto widget = self->widgets[widx::signal];
|
||||
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->colours[1], signalCount, (1 << 7));
|
||||
|
||||
for (auto signalIndex = 0; signalIndex < signalCount; signalIndex++)
|
||||
{
|
||||
auto signal = _signalList[signalIndex];
|
||||
if (signal == _lastSelectedSignal)
|
||||
dropdown::set_highlighted_item(signalIndex);
|
||||
|
||||
auto trainSignalObj = objectmgr::get<train_signal_object>(signal);
|
||||
|
||||
dropdown::add(signalIndex, trainSignalObj->name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case widx::both_directions:
|
||||
{
|
||||
_isSignalBothDirections = 1;
|
||||
input::cancel_tool();
|
||||
input::toolSet(self, widgetIndex, 42);
|
||||
break;
|
||||
}
|
||||
|
||||
case widx::single_direction:
|
||||
{
|
||||
_isSignalBothDirections = 0;
|
||||
input::cancel_tool();
|
||||
input::toolSet(self, widgetIndex, 42);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0x0049E67C
|
||||
static void on_dropdown(window* self, widget_index widgetIndex, int16_t itemIndex)
|
||||
{
|
||||
if (widgetIndex != widx::signal_dropdown)
|
||||
return;
|
||||
|
||||
if (itemIndex != -1)
|
||||
{
|
||||
_lastSelectedSignal = _signalList[itemIndex];
|
||||
_scenarioSignals[_trackType] = _signalList[itemIndex];
|
||||
self->invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
// 0x0049E76F
|
||||
static void on_update(window* self)
|
||||
{
|
||||
common::on_update(self, (1 << 2));
|
||||
}
|
||||
|
||||
// 0x0049E745
|
||||
static void on_tool_update(window& self, const widget_index 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(0x0049E745, regs);
|
||||
}
|
||||
|
||||
// 0x0049E75A
|
||||
static void on_tool_down(window& self, const widget_index 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(0x0049E75A, regs);
|
||||
}
|
||||
|
||||
// 0x0049E499
|
||||
static void prepare_draw(window* self)
|
||||
{
|
||||
common::prepare_draw(self);
|
||||
|
||||
auto trackObj = objectmgr::get<track_object>(_trackType);
|
||||
|
||||
auto args = FormatArguments();
|
||||
args.push(trackObj->name);
|
||||
|
||||
auto trainSignalObject = objectmgr::get<train_signal_object>(_lastSelectedSignal);
|
||||
|
||||
self->widgets[widx::signal].text = trainSignalObject->name;
|
||||
|
||||
common::repositionTabs(self);
|
||||
}
|
||||
|
||||
// 0x0049E501
|
||||
static void draw(window* self, gfx::drawpixelinfo_t* dpi)
|
||||
{
|
||||
self->draw(dpi);
|
||||
common::drawTabs(self, dpi);
|
||||
|
||||
auto trainSignalObject = objectmgr::get<train_signal_object>(_lastSelectedSignal);
|
||||
|
||||
auto xPos = self->x + 3;
|
||||
auto yPos = self->y + 63;
|
||||
auto width = 130;
|
||||
|
||||
{
|
||||
auto args = FormatArguments();
|
||||
args.push(trainSignalObject->var_0C);
|
||||
|
||||
gfx::draw_string_495224(*dpi, xPos, yPos, width, colour::black, string_ids::signal_black, &args);
|
||||
}
|
||||
|
||||
auto imageId = trainSignalObject->var_0E;
|
||||
|
||||
xPos = self->widgets[widx::both_directions].mid_x() + self->x;
|
||||
yPos = self->widgets[widx::both_directions].bottom + self->y - 4;
|
||||
|
||||
gfx::draw_image(dpi, xPos - 8, yPos, imageId);
|
||||
|
||||
gfx::draw_image(dpi, xPos + 8, yPos, imageId + 4);
|
||||
|
||||
xPos = self->widgets[widx::single_direction].mid_x() + self->x;
|
||||
yPos = self->widgets[widx::single_direction].bottom + self->y - 4;
|
||||
|
||||
gfx::draw_image(dpi, xPos, yPos, imageId);
|
||||
|
||||
if (_signalCost != 0x80000000 && _signalCost != 0)
|
||||
{
|
||||
auto args = FormatArguments();
|
||||
args.push<uint32_t>(_signalCost);
|
||||
|
||||
xPos = self->x + 69;
|
||||
yPos = self->widgets[widx::single_direction].bottom + self->y + 5;
|
||||
|
||||
gfx::draw_string_centred(*dpi, xPos, yPos, colour::black, string_ids::build_cost, &args);
|
||||
}
|
||||
}
|
||||
|
||||
void tabReset(window* self)
|
||||
{
|
||||
self->call_on_mouse_down(signal::widx::both_directions);
|
||||
}
|
||||
|
||||
void init_events()
|
||||
{
|
||||
events.on_close = common::on_close;
|
||||
events.on_mouse_up = on_mouse_up;
|
||||
events.on_mouse_down = on_mouse_down;
|
||||
events.on_dropdown = on_dropdown;
|
||||
events.on_update = on_update;
|
||||
events.on_tool_update = on_tool_update;
|
||||
events.on_tool_down = on_tool_down;
|
||||
events.prepare_draw = prepare_draw;
|
||||
events.draw = draw;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,411 @@
|
|||
#include "../../companymgr.h"
|
||||
#include "../../graphics/image_ids.h"
|
||||
#include "../../input.h"
|
||||
#include "../../localisation/FormatArguments.hpp"
|
||||
#include "../../objects/airport_object.h"
|
||||
#include "../../objects/cargo_object.h"
|
||||
#include "../../objects/dock_object.h"
|
||||
#include "../../objects/objectmgr.h"
|
||||
#include "../../objects/road_object.h"
|
||||
#include "../../objects/road_station_object.h"
|
||||
#include "../../objects/track_object.h"
|
||||
#include "../../objects/train_station_object.h"
|
||||
#include "../../stationmgr.h"
|
||||
#include "../../ui/dropdown.h"
|
||||
#include "Construction.h"
|
||||
|
||||
using namespace openloco::interop;
|
||||
using namespace openloco::map;
|
||||
using namespace openloco::map::tilemgr;
|
||||
|
||||
namespace openloco::ui::windows::construction::station
|
||||
{
|
||||
widget_t widgets[] = {
|
||||
commonWidgets(138, 190, string_ids::stringid_2),
|
||||
make_widget({ 3, 45 }, { 132, 12 }, widget_type::wt_18, 1, 0xFFFFFFFF, string_ids::tooltip_select_station_type),
|
||||
make_widget({ 123, 46 }, { 11, 10 }, widget_type::wt_11, 1, string_ids::dropdown, string_ids::tooltip_select_station_type),
|
||||
make_widget({ 35, 60 }, { 68, 68 }, widget_type::wt_3, 1),
|
||||
make_widget({ 112, 104 }, { 24, 24 }, widget_type::wt_9, 1, image_ids::rotate_object, string_ids::rotate_90),
|
||||
widget_end(),
|
||||
};
|
||||
|
||||
window_event_list events;
|
||||
|
||||
// 0x0049E228
|
||||
static void on_mouse_up(window* self, widget_index 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::rotate:
|
||||
_constructionRotation++;
|
||||
_constructionRotation = _constructionRotation & 3;
|
||||
_stationCost = 0x80000000;
|
||||
self->invalidate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename obj_type>
|
||||
void AddStationsToDropdown(const uint8_t stationCount)
|
||||
{
|
||||
for (auto stationIndex = 0; stationIndex < stationCount; stationIndex++)
|
||||
{
|
||||
auto station = _stationList[stationIndex];
|
||||
if (station == _lastSelectedStationType)
|
||||
dropdown::set_highlighted_item(stationIndex);
|
||||
|
||||
auto obj = objectmgr::get<obj_type>(station);
|
||||
dropdown::add(stationIndex, obj->name);
|
||||
}
|
||||
}
|
||||
|
||||
// 0x0049E249
|
||||
static void on_mouse_down(window* self, widget_index widgetIndex)
|
||||
{
|
||||
switch (widgetIndex)
|
||||
{
|
||||
case widx::station_dropdown:
|
||||
{
|
||||
uint8_t stationCount = 0;
|
||||
while (_stationList[stationCount] != 0xFF)
|
||||
stationCount++;
|
||||
|
||||
auto widget = self->widgets[widx::station];
|
||||
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->colours[1], stationCount, (1 << 7));
|
||||
|
||||
if (_byte_1136063 & (1 << 7))
|
||||
{
|
||||
AddStationsToDropdown<airport_object>(stationCount);
|
||||
}
|
||||
else if (_byte_1136063 & (1 << 6))
|
||||
{
|
||||
AddStationsToDropdown<dock_object>(stationCount);
|
||||
}
|
||||
else if (_trackType & (1 << 7))
|
||||
{
|
||||
AddStationsToDropdown<road_station_object>(stationCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddStationsToDropdown<train_station_object>(stationCount);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case widx::image:
|
||||
{
|
||||
input::cancel_tool();
|
||||
input::toolSet(self, widgetIndex, 44);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0x0049E256
|
||||
static void on_dropdown(window* self, widget_index widgetIndex, int16_t itemIndex)
|
||||
{
|
||||
if (widgetIndex == widx::station_dropdown)
|
||||
{
|
||||
if (itemIndex == -1)
|
||||
return;
|
||||
|
||||
auto selectedStation = _stationList[itemIndex];
|
||||
_lastSelectedStationType = selectedStation;
|
||||
|
||||
if (_byte_1136063 & (1 << 7))
|
||||
{
|
||||
_lastAirport = selectedStation;
|
||||
}
|
||||
else if (_byte_1136063 & (1 << 6))
|
||||
{
|
||||
_lastShipPort = selectedStation;
|
||||
}
|
||||
else if (_trackType & (1 << 7))
|
||||
{
|
||||
auto trackType = _trackType & ~(1 << 7);
|
||||
_scenarioRoadStations[trackType] = selectedStation;
|
||||
}
|
||||
else
|
||||
{
|
||||
_scenarioTrainStations[_trackType] = selectedStation;
|
||||
}
|
||||
|
||||
self->invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
// 0x0049E437
|
||||
static void on_update(window* self)
|
||||
{
|
||||
common::on_update(self, (1 << 3));
|
||||
}
|
||||
|
||||
// 0x0049E421
|
||||
static void on_tool_update(window& self, const widget_index 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(0x0049E421, regs);
|
||||
}
|
||||
|
||||
// 0x0049E42C
|
||||
static void on_tool_down(window& self, const widget_index 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(0x0049E42C, regs);
|
||||
}
|
||||
|
||||
// 0x0049DD39
|
||||
static void prepare_draw(window* self)
|
||||
{
|
||||
common::prepare_draw(self);
|
||||
|
||||
self->widgets[widx::rotate].type = widget_type::none;
|
||||
|
||||
auto args = FormatArguments();
|
||||
|
||||
if (_byte_1136063 & (1 << 7))
|
||||
{
|
||||
self->widgets[widx::rotate].type = widget_type::wt_9;
|
||||
|
||||
auto airportObj = objectmgr::get<airport_object>(_lastSelectedStationType);
|
||||
|
||||
self->widgets[widx::station].text = airportObj->name;
|
||||
|
||||
args.push(string_ids::title_airport);
|
||||
}
|
||||
else if (_byte_1136063 & (1 << 6))
|
||||
{
|
||||
auto dockObj = objectmgr::get<dock_object>(_lastSelectedStationType);
|
||||
|
||||
self->widgets[widx::station].text = dockObj->name;
|
||||
|
||||
args.push(string_ids::title_ship_port);
|
||||
}
|
||||
else if (_trackType & (1 << 7))
|
||||
{
|
||||
auto trackType = _trackType & ~(1 << 7);
|
||||
|
||||
auto roadObj = objectmgr::get<road_object>(trackType);
|
||||
|
||||
args.push(roadObj->name);
|
||||
|
||||
auto roadStationObject = objectmgr::get<road_station_object>(_lastSelectedStationType);
|
||||
|
||||
self->widgets[widx::station].text = roadStationObject->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto trackObj = objectmgr::get<track_object>(_trackType);
|
||||
|
||||
args.push(trackObj->name);
|
||||
|
||||
auto trainStationObject = objectmgr::get<train_station_object>(_lastSelectedStationType);
|
||||
|
||||
self->widgets[widx::station].text = trainStationObject->name;
|
||||
}
|
||||
|
||||
common::repositionTabs(self);
|
||||
}
|
||||
|
||||
// 0x0049DE40
|
||||
static void draw(window* self, gfx::drawpixelinfo_t* dpi)
|
||||
{
|
||||
self->draw(dpi);
|
||||
common::drawTabs(self, dpi);
|
||||
|
||||
auto company = companymgr::get(_playerCompany);
|
||||
auto companyColour = company->mainColours.primary;
|
||||
int16_t xPos = self->widgets[widx::image].left + self->x;
|
||||
int16_t yPos = self->widgets[widx::image].top + self->y;
|
||||
|
||||
if (_byte_1136063 & (1 << 7))
|
||||
{
|
||||
auto airportObj = objectmgr::get<airport_object>(_lastSelectedStationType);
|
||||
|
||||
auto imageId = gfx::recolour(airportObj->var_08, companyColour);
|
||||
|
||||
gfx::draw_image(dpi, xPos, yPos, imageId);
|
||||
}
|
||||
else if (_byte_1136063 & (1 << 6))
|
||||
{
|
||||
auto dockObj = objectmgr::get<dock_object>(_lastSelectedStationType);
|
||||
|
||||
auto imageId = gfx::recolour(dockObj->var_08, companyColour);
|
||||
|
||||
gfx::draw_image(dpi, xPos, yPos, imageId);
|
||||
}
|
||||
else if (_trackType & (1 << 7))
|
||||
{
|
||||
auto roadStationObj = objectmgr::get<road_station_object>(_lastSelectedStationType);
|
||||
|
||||
auto imageId = gfx::recolour(roadStationObj->var_0C, companyColour);
|
||||
|
||||
gfx::draw_image(dpi, xPos, yPos, imageId);
|
||||
|
||||
auto colour = _byte_5045FA[companyColour];
|
||||
|
||||
if (!(roadStationObj->flags & road_station_flags::recolourable))
|
||||
{
|
||||
colour = 46;
|
||||
}
|
||||
|
||||
imageId = gfx::recolour(imageId, colour) + 1;
|
||||
|
||||
gfx::draw_image(dpi, xPos, yPos, imageId);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto trainStationObj = objectmgr::get<train_station_object>(_lastSelectedStationType);
|
||||
|
||||
auto imageId = gfx::recolour(trainStationObj->var_0E, companyColour);
|
||||
|
||||
gfx::draw_image(dpi, xPos, yPos, imageId);
|
||||
|
||||
auto colour = _byte_5045FA[companyColour];
|
||||
|
||||
if (!(trainStationObj->flags & train_station_flags::recolourable))
|
||||
{
|
||||
colour = 46;
|
||||
}
|
||||
|
||||
imageId = gfx::recolour(imageId, colour) + 1;
|
||||
|
||||
gfx::draw_image(dpi, xPos, yPos, imageId);
|
||||
}
|
||||
|
||||
if (_stationCost != 0x80000000 && _stationCost != 0)
|
||||
{
|
||||
xPos = self->x + 69;
|
||||
yPos = self->widgets[widx::image].bottom + self->y + 4;
|
||||
|
||||
auto args = FormatArguments();
|
||||
args.push<uint32_t>(_stationCost);
|
||||
|
||||
gfx::draw_string_centred(*dpi, xPos, yPos, colour::black, string_ids::build_cost, &args);
|
||||
}
|
||||
|
||||
xPos = self->x + 3;
|
||||
yPos = self->widgets[widx::image].bottom + self->y + 16;
|
||||
auto width = self->width - 4;
|
||||
gfx::draw_rect_inset(dpi, xPos, yPos, width, 1, self->colours[1], (1 << 5));
|
||||
|
||||
if (!(_byte_522096 & (1 << 3)))
|
||||
return;
|
||||
|
||||
auto args = FormatArguments();
|
||||
|
||||
if (_constructingStationId == 0xFFFFFFFF)
|
||||
{
|
||||
args.push(string_ids::new_station);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto station = stationmgr::get(_constructingStationId);
|
||||
args.push(station->name);
|
||||
args.push(station->town);
|
||||
}
|
||||
|
||||
xPos = self->x + 69;
|
||||
yPos = self->widgets[widx::image].bottom + self->y + 18;
|
||||
width = self->width - 4;
|
||||
gfx::draw_string_centred_clipped(*dpi, xPos, yPos, width, colour::black, string_ids::new_station_buffer, &args);
|
||||
|
||||
xPos = self->x + 2;
|
||||
yPos = self->widgets[widx::image].bottom + self->y + 29;
|
||||
gfx::point_t origin = { xPos, yPos };
|
||||
|
||||
gfx::draw_string_494B3F(*dpi, &origin, colour::black, string_ids::catchment_area_accepts);
|
||||
|
||||
if (_constructingStationAcceptedCargoTypes == 0)
|
||||
{
|
||||
gfx::draw_string_494B3F(*dpi, origin.x, origin.y, colour::black, string_ids::catchment_area_nothing);
|
||||
}
|
||||
else
|
||||
{
|
||||
yPos--;
|
||||
for (uint8_t i = 0; i < objectmgr::get_max_objects(object_type::cargo); i++)
|
||||
{
|
||||
if (_constructingStationAcceptedCargoTypes & (1 << i))
|
||||
{
|
||||
auto xPosMax = self->x + self->width - 12;
|
||||
if (origin.x <= xPosMax)
|
||||
{
|
||||
auto cargoObj = objectmgr::get<cargo_object>(i);
|
||||
|
||||
gfx::draw_image(dpi, origin.x, origin.y, cargoObj->unit_inline_sprite);
|
||||
origin.x += 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xPos = self->x + 2;
|
||||
yPos = self->widgets[widx::image].bottom + self->y + 49;
|
||||
origin = { xPos, yPos };
|
||||
|
||||
gfx::draw_string_494B3F(*dpi, &origin, colour::black, string_ids::catchment_area_produces);
|
||||
|
||||
if (_constructingStationProducedCargoTypes == 0)
|
||||
{
|
||||
gfx::draw_string_494B3F(*dpi, origin.x, origin.y, colour::black, string_ids::catchment_area_nothing);
|
||||
}
|
||||
else
|
||||
{
|
||||
yPos--;
|
||||
for (uint8_t i = 0; i < objectmgr::get_max_objects(object_type::cargo); i++)
|
||||
{
|
||||
if (_constructingStationProducedCargoTypes & (1 << i))
|
||||
{
|
||||
auto xPosMax = self->x + self->width - 12;
|
||||
if (origin.x <= xPosMax)
|
||||
{
|
||||
auto cargoObj = objectmgr::get<cargo_object>(i);
|
||||
|
||||
gfx::draw_image(dpi, origin.x, origin.y, cargoObj->unit_inline_sprite);
|
||||
origin.x += 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tabReset(window* self)
|
||||
{
|
||||
self->call_on_mouse_down(station::widx::image);
|
||||
}
|
||||
|
||||
void init_events()
|
||||
{
|
||||
events.on_close = common::on_close;
|
||||
events.on_mouse_up = on_mouse_up;
|
||||
events.on_mouse_down = on_mouse_down;
|
||||
events.on_dropdown = on_dropdown;
|
||||
events.on_update = on_update;
|
||||
events.on_tool_update = on_tool_update;
|
||||
events.on_tool_down = on_tool_down;
|
||||
events.prepare_draw = prepare_draw;
|
||||
events.draw = draw;
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
#include "../input.h"
|
||||
#include "../interop/interop.hpp"
|
||||
#include "../ui/WindowManager.h"
|
||||
|
||||
using namespace openloco::interop;
|
||||
|
||||
namespace openloco::ui::windows::construction
|
||||
{
|
||||
namespace widx
|
||||
{
|
||||
enum
|
||||
{
|
||||
close = 2,
|
||||
tab_0 = 4,
|
||||
tab_1,
|
||||
tab_2,
|
||||
tab_3,
|
||||
construct = 28,
|
||||
remove,
|
||||
place,
|
||||
};
|
||||
}
|
||||
|
||||
// 0x004A3B0D
|
||||
window* openWithFlags(const uint32_t flags)
|
||||
{
|
||||
registers regs;
|
||||
regs.ecx = flags;
|
||||
call(0x004A3B0D, regs);
|
||||
return (window*)regs.esi;
|
||||
}
|
||||
|
||||
// 0x0049D3F6
|
||||
void on_mouse_up(window& w, const uint16_t widgetIndex)
|
||||
{
|
||||
// Allow shift key to repeat the action multiple times
|
||||
// This is useful for building very long tracks.
|
||||
int multiplier = 1;
|
||||
if (input::has_key_modifier(input::key_modifier::shift))
|
||||
{
|
||||
multiplier = 10;
|
||||
}
|
||||
|
||||
registers regs;
|
||||
regs.edx = widgetIndex;
|
||||
regs.esi = (int32_t)&w;
|
||||
switch (widgetIndex)
|
||||
{
|
||||
case widx::close:
|
||||
WindowManager::close(&w);
|
||||
break;
|
||||
case widx::tab_0:
|
||||
case widx::tab_1:
|
||||
case widx::tab_2:
|
||||
case widx::tab_3:
|
||||
call(0x0049D93A, regs);
|
||||
break;
|
||||
case widx::construct:
|
||||
for (int i = 0; i < multiplier; i++)
|
||||
{
|
||||
call(0x0049F92D, regs);
|
||||
}
|
||||
break;
|
||||
case widx::remove:
|
||||
for (int i = 0; i < multiplier; i++)
|
||||
{
|
||||
call(0x004A0121, regs);
|
||||
}
|
||||
break;
|
||||
case widx::place:
|
||||
call(0x0049D7DC, regs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,6 +8,8 @@
|
|||
#include "../interop/interop.hpp"
|
||||
#include "../localisation/FormatArguments.hpp"
|
||||
#include "../localisation/string_ids.h"
|
||||
#include "../map/tile_loop.hpp"
|
||||
#include "../map/tilemgr.h"
|
||||
#include "../objects/cargo_object.h"
|
||||
#include "../objects/interface_skin_object.h"
|
||||
#include "../objects/objectmgr.h"
|
||||
|
@ -18,10 +20,13 @@
|
|||
#include "../widget.h"
|
||||
|
||||
using namespace openloco::interop;
|
||||
using namespace openloco::map;
|
||||
|
||||
namespace openloco::ui::windows::station
|
||||
{
|
||||
static loco_global<uint16_t, 0x00112C786> word_112C786;
|
||||
static loco_global<uint16_t[0x24000], 0x000F00484> _byte_F00484;
|
||||
static loco_global<uint16_t, 0x00F24484> _mapSelectionFlags;
|
||||
static loco_global<uint16_t, 0x00112C786> _lastSelectedStation;
|
||||
|
||||
static loco_global<string_id, 0x009C68E8> gGameCommandErrorTitle;
|
||||
|
||||
|
@ -361,7 +366,7 @@ namespace openloco::ui::windows::station
|
|||
common::repositionTabs(self);
|
||||
|
||||
self->activated_widgets &= ~(1 << widx::station_catchment);
|
||||
if (self->number == word_112C786)
|
||||
if (self->number == _lastSelectedStation)
|
||||
self->activated_widgets |= (1 << widx::station_catchment);
|
||||
}
|
||||
|
||||
|
@ -427,15 +432,14 @@ namespace openloco::ui::windows::station
|
|||
break;
|
||||
|
||||
case widx::station_catchment:
|
||||
auto windowNumber = self->number;
|
||||
if (self->number == word_112C786)
|
||||
windowNumber = -1;
|
||||
{
|
||||
station_id_t windowNumber = self->number;
|
||||
if (windowNumber == _lastSelectedStation)
|
||||
windowNumber = station_id::null;
|
||||
|
||||
// 0x0049271A
|
||||
registers regs;
|
||||
regs.ax = windowNumber;
|
||||
call(0x0049271A, regs);
|
||||
showStationCatchment(windowNumber);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -718,6 +722,65 @@ namespace openloco::ui::windows::station
|
|||
}
|
||||
}
|
||||
|
||||
// 0x00491BC6
|
||||
static void sub_491BC6()
|
||||
{
|
||||
tile_loop tileLoop;
|
||||
|
||||
for (uint32_t posId = 0; posId < 0x24000; posId++)
|
||||
{
|
||||
if (_byte_F00484[posId] & (1 << 0))
|
||||
{
|
||||
tilemgr::map_invalidate_tile_full(tileLoop.current());
|
||||
}
|
||||
tileLoop.next();
|
||||
}
|
||||
}
|
||||
|
||||
// 0x00491D70
|
||||
static void setStationCatchmentDisplay(openloco::station* station, uint16_t dx)
|
||||
{
|
||||
registers regs;
|
||||
regs.ebp = uint32_t(station);
|
||||
regs.dx = dx;
|
||||
call(0x00491D70, regs);
|
||||
}
|
||||
|
||||
// 0x0049271A
|
||||
void showStationCatchment(uint16_t stationId)
|
||||
{
|
||||
if (stationId == _lastSelectedStation)
|
||||
return;
|
||||
|
||||
uint16_t oldStationId = *_lastSelectedStation;
|
||||
_lastSelectedStation = stationId;
|
||||
|
||||
if (oldStationId != station_id::null)
|
||||
{
|
||||
if (input::hasMapSelectionFlag(input::map_selection_flags::catchment_area))
|
||||
{
|
||||
WindowManager::invalidate(WindowType::station, oldStationId);
|
||||
sub_491BC6();
|
||||
input::resetMapSelectionFlag(input::map_selection_flags::catchment_area);
|
||||
}
|
||||
}
|
||||
|
||||
auto newStationId = _lastSelectedStation;
|
||||
|
||||
if (newStationId != station_id::null)
|
||||
{
|
||||
ui::windows::construction::sub_4A6FAC();
|
||||
auto station = stationmgr::get(_lastSelectedStation);
|
||||
|
||||
setStationCatchmentDisplay(station, 0);
|
||||
input::setMapSelectionFlags(input::map_selection_flags::catchment_area);
|
||||
|
||||
WindowManager::invalidate(WindowType::station, newStationId);
|
||||
|
||||
sub_491BC6();
|
||||
}
|
||||
}
|
||||
|
||||
namespace common
|
||||
{
|
||||
struct TabInformation
|
||||
|
@ -847,12 +910,9 @@ namespace openloco::ui::windows::station
|
|||
static void switchTab(window* self, widget_index widgetIndex)
|
||||
{
|
||||
if (widgetIndex == widx::tab_cargo)
|
||||
if (self->number == word_112C786)
|
||||
if (self->number == _lastSelectedStation)
|
||||
{
|
||||
// 0x0049271A
|
||||
registers regs;
|
||||
regs.ax = -1;
|
||||
call(0x0049271A, regs);
|
||||
showStationCatchment(station_id::null);
|
||||
}
|
||||
|
||||
if (input::is_tool_active(self->type, self->number))
|
||||
|
|
Loading…
Reference in New Issue