1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-16 11:33:03 +01:00

Allow maps to be resized to non-rectangular shapes

This commit is contained in:
Hielke Morsink
2022-05-15 22:25:45 +02:00
parent 673ec0fa10
commit 8d14016c3f
7 changed files with 129 additions and 56 deletions

View File

@@ -2258,7 +2258,7 @@ STR_3208 :Track Designs Manager
STR_3209 :Back to Previous Step:
STR_3210 :Forward to Next Step:
STR_3211 :Map size:
STR_3212 :{COMMA16} × {COMMA16}
STR_3212 :{POP16}{COMMA16}
STR_3213 :Cant decrease map size any further
STR_3214 :Cant increase map size any further
STR_3215 :Too close to edge of map
@@ -3603,6 +3603,7 @@ STR_6494 :Group by ride type
STR_6495 :Group rides by ride types instead of showing each vehicle separately.
STR_6496 :{WINDOW_COLOUR_2}{STRINGID}
STR_6497 :Click on a tile to show its tile elements.{NEWLINE}Ctrl + click a tile element to select it directly.
STR_6498 :Enable to maintain square map shape.
#############
# Scenarios #

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

View File

@@ -529,6 +529,11 @@
"x_offset": 4,
"y_offset": 2
},
{
"path": "icons/link_chain.png",
"x_offset": 2,
"y_offset": 2
},
{
"path": "font/latin/ae-uc-small.png",
"y_offset": 0,

View File

@@ -72,25 +72,29 @@ enum WindowMapWidgetIdx
WIDX_BACKGROUND,
WIDX_TITLE,
WIDX_CLOSE,
WIDX_RESIZE = 3,
WIDX_PEOPLE_TAB = 4,
WIDX_RIDES_TAB = 5,
WIDX_MAP = 6,
WIDX_MAP_SIZE_SPINNER = 7,
WIDX_MAP_SIZE_SPINNER_UP = 8,
WIDX_MAP_SIZE_SPINNER_DOWN = 9,
WIDX_SET_LAND_RIGHTS = 10,
WIDX_BUILD_PARK_ENTRANCE = 11,
WIDX_PEOPLE_STARTING_POSITION = 12,
WIDX_LAND_TOOL = 13,
WIDX_LAND_TOOL_SMALLER = 14,
WIDX_LAND_TOOL_LARGER = 15,
WIDX_LAND_OWNED_CHECKBOX = 16,
WIDX_CONSTRUCTION_RIGHTS_OWNED_CHECKBOX = 17,
WIDX_LAND_SALE_CHECKBOX = 18,
WIDX_CONSTRUCTION_RIGHTS_SALE_CHECKBOX = 19,
WIDX_ROTATE_90 = 20,
WIDX_MAP_GENERATOR = 21
WIDX_RESIZE,
WIDX_PEOPLE_TAB,
WIDX_RIDES_TAB,
WIDX_MAP,
WIDX_MAP_SIZE_SPINNER_Y,
WIDX_MAP_SIZE_SPINNER_Y_UP,
WIDX_MAP_SIZE_SPINNER_Y_DOWN,
WIDX_MAP_SIZE_LINK,
WIDX_MAP_SIZE_SPINNER_X,
WIDX_MAP_SIZE_SPINNER_X_UP,
WIDX_MAP_SIZE_SPINNER_X_DOWN,
WIDX_SET_LAND_RIGHTS,
WIDX_BUILD_PARK_ENTRANCE,
WIDX_PEOPLE_STARTING_POSITION,
WIDX_LAND_TOOL,
WIDX_LAND_TOOL_SMALLER,
WIDX_LAND_TOOL_LARGER,
WIDX_LAND_OWNED_CHECKBOX,
WIDX_CONSTRUCTION_RIGHTS_OWNED_CHECKBOX,
WIDX_LAND_SALE_CHECKBOX,
WIDX_CONSTRUCTION_RIGHTS_SALE_CHECKBOX,
WIDX_ROTATE_90,
WIDX_MAP_GENERATOR
};
validate_global_widx(WC_MAP, WIDX_ROTATE_90);
@@ -102,7 +106,9 @@ static rct_widget window_map_widgets[] = {
MakeRemapWidget ({ 3, 17}, { 31, 27}, WindowWidgetType::ColourBtn, WindowColour::Secondary, SPR_TAB, STR_SHOW_PEOPLE_ON_MAP_TIP ),
MakeRemapWidget ({ 34, 17}, { 31, 27}, WindowWidgetType::ColourBtn, WindowColour::Secondary, SPR_TAB, STR_SHOW_RIDES_STALLS_ON_MAP_TIP ),
MakeWidget ({ 3, 46}, {239, 180}, WindowWidgetType::Scroll, WindowColour::Secondary, SCROLL_BOTH ),
MakeSpinnerWidgets({104, 229}, { 95, 12}, WindowWidgetType::Spinner, WindowColour::Secondary, STR_MAP_SIZE_VALUE ), // NB: 3 widgets
MakeSpinnerWidgets({102, 229}, { 50, 12}, WindowWidgetType::Spinner, WindowColour::Secondary, STR_COMMA16 ), // NB: 3 widgets
MakeWidget ({153, 230}, { 20, 12}, WindowWidgetType::FlatBtn, WindowColour::Secondary, SPR_G2_LINK_CHAIN, STR_MAINTAIN_SQUARE_MAP_TOOLTIP ),
MakeSpinnerWidgets({174, 229}, { 50, 12}, WindowWidgetType::Spinner, WindowColour::Secondary, STR_POP16_COMMA16 ), // NB: 3 widgets
MakeWidget ({ 4, 1}, { 24, 24}, WindowWidgetType::FlatBtn, WindowColour::Secondary, SPR_BUY_LAND_RIGHTS, STR_SELECT_PARK_OWNED_LAND_TIP ),
MakeWidget ({ 4, 1}, { 24, 24}, WindowWidgetType::FlatBtn, WindowColour::Secondary, SPR_PARK_ENTRANCE, STR_BUILD_PARK_ENTRANCE_TIP ),
MakeWidget ({ 28, 1}, { 24, 24}, WindowWidgetType::FlatBtn, WindowColour::Secondary, 0xFFFFFFFF, STR_SET_STARTING_POSITIONS_TIP ),
@@ -140,8 +146,9 @@ public:
{
widgets = window_map_widgets;
hold_down_widgets = (1ULL << WIDX_MAP_SIZE_SPINNER_UP) | (1ULL << WIDX_MAP_SIZE_SPINNER_DOWN)
| (1ULL << WIDX_LAND_TOOL_LARGER) | (1ULL << WIDX_LAND_TOOL_SMALLER);
hold_down_widgets = (1ULL << WIDX_MAP_SIZE_SPINNER_Y_UP) | (1ULL << WIDX_MAP_SIZE_SPINNER_Y_DOWN)
| (1ULL << WIDX_MAP_SIZE_SPINNER_X_UP) | (1ULL << WIDX_MAP_SIZE_SPINNER_X_DOWN) | (1ULL << WIDX_LAND_TOOL_LARGER)
| (1ULL << WIDX_LAND_TOOL_SMALLER);
InitScrollWidgets();
@@ -251,8 +258,12 @@ public:
case WIDX_LAND_TOOL:
InputLandSize();
break;
case WIDX_MAP_SIZE_SPINNER:
InputMapSize();
case WIDX_MAP_SIZE_SPINNER_Y:
case WIDX_MAP_SIZE_SPINNER_X:
InputMapSize(widgetIndex);
break;
case WIDX_MAP_SIZE_LINK:
_mapWidthAndHeightLinked = !_mapWidthAndHeightLinked;
break;
case WIDX_MAP_GENERATOR:
context_open_window(WC_MAPGEN);
@@ -274,10 +285,20 @@ public:
{
switch (widgetIndex)
{
case WIDX_MAP_SIZE_SPINNER_UP:
case WIDX_MAP_SIZE_SPINNER_Y_UP:
_resizeDirection = ResizeDirection::Y;
IncreaseMapSize();
break;
case WIDX_MAP_SIZE_SPINNER_DOWN:
case WIDX_MAP_SIZE_SPINNER_Y_DOWN:
_resizeDirection = ResizeDirection::Y;
DecreaseMapSize();
break;
case WIDX_MAP_SIZE_SPINNER_X_UP:
_resizeDirection = ResizeDirection::X;
IncreaseMapSize();
break;
case WIDX_MAP_SIZE_SPINNER_X_DOWN:
_resizeDirection = ResizeDirection::X;
DecreaseMapSize();
break;
case WIDX_LAND_TOOL_SMALLER:
@@ -577,7 +598,8 @@ public:
}
break;
}
case WIDX_MAP_SIZE_SPINNER:
case WIDX_MAP_SIZE_SPINNER_Y:
case WIDX_MAP_SIZE_SPINNER_X:
{
char* end;
std::string textStr = std::string(text);
@@ -588,7 +610,13 @@ public:
size += 2;
size = std::clamp(size, MINIMUM_MAP_SIZE_TECHNICAL, MAXIMUM_MAP_SIZE_TECHNICAL);
auto changeMapSizeAction = ChangeMapSizeAction({ size, size });
TileCoordsXY newMapSize = gMapSize;
if (_resizeDirection != ResizeDirection::X)
newMapSize.y = size;
if (_resizeDirection != ResizeDirection::Y)
newMapSize.x = size;
auto changeMapSizeAction = ChangeMapSizeAction(newMapSize);
GameActions::Execute(&changeMapSizeAction);
Invalidate();
}
@@ -689,14 +717,8 @@ public:
void OnPrepareDraw() override
{
// Set the pressed widgets
pressed_widgets &= (1ULL << WIDX_PEOPLE_TAB);
pressed_widgets &= (1ULL << WIDX_RIDES_TAB);
pressed_widgets &= (1ULL << WIDX_MAP);
pressed_widgets &= (1ULL << WIDX_LAND_OWNED_CHECKBOX);
pressed_widgets &= (1ULL << WIDX_CONSTRUCTION_RIGHTS_OWNED_CHECKBOX);
pressed_widgets &= (1ULL << WIDX_LAND_SALE_CHECKBOX);
pressed_widgets &= (1ULL << WIDX_CONSTRUCTION_RIGHTS_SALE_CHECKBOX);
pressed_widgets = 0;
SetWidgetPressed(WIDX_MAP_SIZE_LINK, _mapWidthAndHeightLinked);
pressed_widgets |= (1ULL << (WIDX_PEOPLE_TAB + selected_tab));
pressed_widgets |= (1ULL << WIDX_LAND_TOOL);
@@ -712,6 +734,9 @@ public:
if (_activeTool & (1 << 0))
pressed_widgets |= (1ULL << WIDX_CONSTRUCTION_RIGHTS_OWNED_CHECKBOX);
// Set disabled widgets
SetWidgetDisabled(WIDX_MAP_SIZE_LINK, gMapSize.x != gMapSize.y);
// Resize widgets to window size
widgets[WIDX_BACKGROUND].right = width - 1;
widgets[WIDX_BACKGROUND].bottom = height - 1;
@@ -729,12 +754,20 @@ public:
else
widgets[WIDX_MAP].bottom = height - 1 - 14;
widgets[WIDX_MAP_SIZE_SPINNER].top = height - 15;
widgets[WIDX_MAP_SIZE_SPINNER].bottom = height - 4;
widgets[WIDX_MAP_SIZE_SPINNER_UP].top = height - 14;
widgets[WIDX_MAP_SIZE_SPINNER_UP].bottom = height - 5;
widgets[WIDX_MAP_SIZE_SPINNER_DOWN].top = height - 14;
widgets[WIDX_MAP_SIZE_SPINNER_DOWN].bottom = height - 5;
widgets[WIDX_MAP_SIZE_SPINNER_Y].top = height - 15;
widgets[WIDX_MAP_SIZE_SPINNER_Y].bottom = height - 4;
widgets[WIDX_MAP_SIZE_SPINNER_Y_UP].top = height - 14;
widgets[WIDX_MAP_SIZE_SPINNER_Y_UP].bottom = height - 5;
widgets[WIDX_MAP_SIZE_SPINNER_Y_DOWN].top = height - 14;
widgets[WIDX_MAP_SIZE_SPINNER_Y_DOWN].bottom = height - 5;
widgets[WIDX_MAP_SIZE_LINK].top = height - 15;
widgets[WIDX_MAP_SIZE_LINK].bottom = height - 4;
widgets[WIDX_MAP_SIZE_SPINNER_X].top = height - 15;
widgets[WIDX_MAP_SIZE_SPINNER_X].bottom = height - 4;
widgets[WIDX_MAP_SIZE_SPINNER_X_UP].top = height - 14;
widgets[WIDX_MAP_SIZE_SPINNER_X_UP].bottom = height - 5;
widgets[WIDX_MAP_SIZE_SPINNER_X_DOWN].top = height - 14;
widgets[WIDX_MAP_SIZE_SPINNER_X_DOWN].bottom = height - 5;
widgets[WIDX_SET_LAND_RIGHTS].top = height - 70;
widgets[WIDX_SET_LAND_RIGHTS].bottom = height - 70 + 23;
@@ -766,7 +799,7 @@ public:
}
// Disable all scenario editor related widgets
for (int32_t i = WIDX_MAP_SIZE_SPINNER; i <= WIDX_MAP_GENERATOR; i++)
for (int32_t i = WIDX_MAP_SIZE_SPINNER_Y; i <= WIDX_MAP_GENERATOR; i++)
{
widgets[i].type = WindowWidgetType::Empty;
}
@@ -848,6 +881,7 @@ public:
STR_MAP_RIDE, STR_MAP_FOOD_STALL, STR_MAP_DRINK_STALL, STR_MAP_SOUVENIR_STALL,
STR_MAP_INFO_KIOSK, STR_MAP_FIRST_AID, STR_MAP_CASH_MACHINE, STR_MAP_TOILET,
};
static_assert(std::size(RideKeyColours) == std::size(_mapLabels));
for (uint32_t i = 0; i < std::size(RideKeyColours); i++)
{
@@ -866,7 +900,7 @@ public:
else if (!WidgetIsActiveTool(this, WIDX_SET_LAND_RIGHTS))
{
DrawTextBasic(
&dpi, windowPos + ScreenCoordsXY{ 4, widgets[WIDX_MAP_SIZE_SPINNER].top + 1 }, STR_MAP_SIZE, {},
&dpi, windowPos + ScreenCoordsXY{ 4, widgets[WIDX_MAP_SIZE_SPINNER_Y].top + 1 }, STR_MAP_SIZE, {},
{ colours[1] });
}
}
@@ -930,13 +964,25 @@ private:
void IncreaseMapSize()
{
auto increaseMapSizeAction = ChangeMapSizeAction({ gMapSize.x + 1, gMapSize.y + 1 });
auto newMapSize = gMapSize;
if (IsWidgetPressed(WIDX_MAP_SIZE_LINK) || _resizeDirection == ResizeDirection::Y)
newMapSize.y++;
if (IsWidgetPressed(WIDX_MAP_SIZE_LINK) || _resizeDirection == ResizeDirection::X)
newMapSize.x++;
auto increaseMapSizeAction = ChangeMapSizeAction(newMapSize);
GameActions::Execute(&increaseMapSizeAction);
}
void DecreaseMapSize()
{
auto decreaseMapSizeAction = ChangeMapSizeAction({ gMapSize.x - 1, gMapSize.y - 1 });
auto newMapSize = gMapSize;
if (IsWidgetPressed(WIDX_MAP_SIZE_LINK) || _resizeDirection == ResizeDirection::Y)
newMapSize.y--;
if (IsWidgetPressed(WIDX_MAP_SIZE_LINK) || _resizeDirection == ResizeDirection::X)
newMapSize.x--;
auto decreaseMapSizeAction = ChangeMapSizeAction(newMapSize);
GameActions::Execute(&decreaseMapSizeAction);
}
@@ -1246,17 +1292,22 @@ private:
{
widgets[WIDX_BUILD_PARK_ENTRANCE].type = WindowWidgetType::FlatBtn;
widgets[WIDX_PEOPLE_STARTING_POSITION].type = WindowWidgetType::FlatBtn;
widgets[WIDX_MAP_SIZE_SPINNER].type = WindowWidgetType::Spinner;
widgets[WIDX_MAP_SIZE_SPINNER_UP].type = WindowWidgetType::Button;
widgets[WIDX_MAP_SIZE_SPINNER_DOWN].type = WindowWidgetType::Button;
widgets[WIDX_MAP_SIZE_SPINNER_Y].type = WindowWidgetType::Spinner;
widgets[WIDX_MAP_SIZE_SPINNER_Y_UP].type = WindowWidgetType::Button;
widgets[WIDX_MAP_SIZE_SPINNER_Y_DOWN].type = WindowWidgetType::Button;
widgets[WIDX_MAP_SIZE_LINK].type = WindowWidgetType::FlatBtn;
widgets[WIDX_MAP_SIZE_SPINNER_X].type = WindowWidgetType::Spinner;
widgets[WIDX_MAP_SIZE_SPINNER_X_UP].type = WindowWidgetType::Button;
widgets[WIDX_MAP_SIZE_SPINNER_X_DOWN].type = WindowWidgetType::Button;
// Only show this in the scenario editor, even when in sandbox mode.
if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR)
widgets[WIDX_MAP_GENERATOR].type = WindowWidgetType::Button;
// Push width (Y) and height (X) to the common formatter arguments for the map size spinners to use
auto ft = Formatter::Common();
ft.Add<uint16_t>(gMapSize.x - 2);
ft.Add<uint16_t>(gMapSize.y - 2);
ft.Add<uint16_t>(gMapSize.x - 2);
}
void InputLandSize()
@@ -1267,12 +1318,17 @@ private:
TextInputOpen(WIDX_LAND_TOOL, STR_SELECTION_SIZE, STR_ENTER_SELECTION_SIZE, ft, STR_NONE, STR_NONE, 3);
}
void InputMapSize()
void InputMapSize(rct_widgetindex callingWidget)
{
if (IsWidgetPressed(WIDX_MAP_SIZE_LINK))
_resizeDirection = ResizeDirection::Both;
else
_resizeDirection = (callingWidget == WIDX_MAP_SIZE_SPINNER_Y) ? ResizeDirection::Y : ResizeDirection::X;
Formatter ft;
ft.Add<int16_t>(MINIMUM_MAP_SIZE_PRACTICAL);
ft.Add<int16_t>(MAXIMUM_MAP_SIZE_PRACTICAL);
TextInputOpen(WIDX_MAP_SIZE_SPINNER, STR_MAP_SIZE_2, STR_ENTER_MAP_SIZE, ft, STR_NONE, STR_NONE, 4);
TextInputOpen(callingWidget, STR_MAP_SIZE_2, STR_ENTER_MAP_SIZE, ft, STR_NONE, STR_NONE, 4);
}
CoordsXY ScreenToMap(ScreenCoordsXY screenCoords)
@@ -1327,6 +1383,13 @@ private:
uint32_t _currentLine;
uint16_t _landRightsToolSize;
std::vector<uint8_t> _mapImageData;
bool _mapWidthAndHeightLinked{ true };
enum class ResizeDirection
{
Both,
X,
Y,
} _resizeDirection{ ResizeDirection::Both };
static constexpr const uint16_t RideKeyColours[] = {
MapColour(PALETTE_INDEX_61), // COLOUR_KEY_RIDE

View File

@@ -527,7 +527,7 @@ enum
#define WC_PEEP__WIDX_PICKUP 14
#define WC_TRACK_DESIGN_LIST__WIDX_ROTATE 8
#define WC_TRACK_DESIGN_PLACE__WIDX_ROTATE 3
#define WC_MAP__WIDX_ROTATE_90 20
#define WC_MAP__WIDX_ROTATE_90 24
#define WC_EDITOR_OBJECT_SELECTION__WIDX_TAB_1 21
#define WC_STAFF__WIDX_PICKUP 9
#define WC_TILE_INSPECTOR__WIDX_BUTTON_ROTATE 13

View File

@@ -2379,7 +2379,7 @@ enum : uint16_t
STR_BACK_TO_PREVIOUS_STEP = 3209,
STR_FORWARD_TO_NEXT_STEP = 3210,
STR_MAP_SIZE = 3211,
STR_MAP_SIZE_VALUE = 3212,
STR_POP16_COMMA16 = 3212,
STR_CANT_DECREASE_MAP_SIZE_ANY_FURTHER = 3213,
STR_CANT_INCREASE_MAP_SIZE_ANY_FURTHER = 3214,
STR_TOO_CLOSE_TO_EDGE_OF_MAP = 3215,
@@ -3875,6 +3875,8 @@ enum : uint16_t
STR_TILE_INSPECTOR_SELECT_TILE_HINT = 6497,
STR_MAINTAIN_SQUARE_MAP_TOOLTIP = 6498,
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
/* MAX_STR_COUNT = 32768 */ // MAX_STR_COUNT - upper limit for number of strings, not the current count strings
};

View File

@@ -895,7 +895,9 @@ enum
SPR_G2_BUTTON_HIDE_PARTIAL = SPR_G2_BEGIN + 147,
SPR_G2_BUTTON_HIDE_FULL = SPR_G2_BEGIN + 148,
SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 149,
SPR_G2_LINK_CHAIN = SPR_G2_BEGIN + 149,
SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 150,
SPR_G2_AE_UPPER = SPR_G2_CHAR_BEGIN,
SPR_G2_AE_LOWER = SPR_G2_CHAR_BEGIN + 1,