diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 9eeea5e23d..c649824c2c 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3669,9 +3669,11 @@ STR_6347 :Path additions cannot be placed on level crossings! STR_6348 :Remove level crossing first! STR_6349 :Random title sequence STR_6350 :Scatter -STR_6351 :{BLACK}Size -STR_6352 :{BLACK}Amount -STR_6353 :Scenery Scatter Tool +STR_6351 :Scenery Scatter Tool +STR_6352 :Density +STR_6353 :{SMALLFONT}{BLACK}Low density +STR_6354 :{SMALLFONT}{BLACK}Medium density +STR_6355 :{SMALLFONT}{BLACK}High density ############# # Scenarios # diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index df7fda9fd4..05f88aa104 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -462,6 +462,15 @@ "x_offset": 1, "y_offset": 5 }, + { + "path": "tool/scenery_scatter_low.png" + }, + { + "path": "tool/scenery_scatter_medium.png" + }, + { + "path": "tool/scenery_scatter_high.png" + }, { "path": "font/latin/ae-uc-small.png", "y_offset": 0, diff --git a/resources/g2/tool/scenery_scatter_high.png b/resources/g2/tool/scenery_scatter_high.png new file mode 100644 index 0000000000..1469782a2a Binary files /dev/null and b/resources/g2/tool/scenery_scatter_high.png differ diff --git a/resources/g2/tool/scenery_scatter_low.png b/resources/g2/tool/scenery_scatter_low.png new file mode 100644 index 0000000000..40a2752107 Binary files /dev/null and b/resources/g2/tool/scenery_scatter_low.png differ diff --git a/resources/g2/tool/scenery_scatter_medium.png b/resources/g2/tool/scenery_scatter_medium.png new file mode 100644 index 0000000000..93dfba41f1 Binary files /dev/null and b/resources/g2/tool/scenery_scatter_medium.png differ diff --git a/src/openrct2-ui/windows/Scenery.cpp b/src/openrct2-ui/windows/Scenery.cpp index dfd564eaf8..a384765ab1 100644 --- a/src/openrct2-ui/windows/Scenery.cpp +++ b/src/openrct2-ui/windows/Scenery.cpp @@ -60,7 +60,7 @@ uint16_t gWindowSceneryTabSelections[SCENERY_WINDOW_TABS]; uint8_t gWindowSceneryActiveTabIndex; rct_window* gWindowSceneryScatterWindow; uint16_t gWindowSceneryScatterSize; -uint16_t gWindowSceneryScatterAmount; +ScatterToolDensity gWindowSceneryScatterDensity; bool gWindowSceneryScatterEnabled; uint8_t gWindowSceneryPaintEnabled; uint8_t gWindowSceneryRotation; @@ -493,7 +493,7 @@ rct_window* window_scenery_open() gWindowSceneryScatterWindow = nullptr; gWindowSceneryScatterSize = 16; - gWindowSceneryScatterAmount = 35; + gWindowSceneryScatterDensity = ScatterToolDensity::MediumDensity; window->min_width = WINDOW_SCENERY_WIDTH; window->max_width = WINDOW_SCENERY_WIDTH; diff --git a/src/openrct2-ui/windows/SceneryScatter.cpp b/src/openrct2-ui/windows/SceneryScatter.cpp index 9cb6a9094b..a0b7d17fef 100644 --- a/src/openrct2-ui/windows/SceneryScatter.cpp +++ b/src/openrct2-ui/windows/SceneryScatter.cpp @@ -15,8 +15,6 @@ #include #include -#define MAX_AMOUNT 100 - enum WINDOW_CLEAR_SCENERY_WIDGET_IDX { WIDX_BACKGROUND, @@ -25,24 +23,26 @@ enum WINDOW_CLEAR_SCENERY_WIDGET_IDX WIDX_PREVIEW, WIDX_DECREMENT, WIDX_INCREMENT, - WIDX_AMOUNT, - WIDX_ADECREMENT, - WIDX_AINCREMENT + WIDX_DENSITY, + WIDX_DENSITY_LOW, + WIDX_DENSITY_MEDIUM, + WIDX_DENSITY_HIGH }; // clang-format off static rct_widget window_scenery_scatter_widgets[] = { - { WWT_FRAME, 1, 0, 70, 0, 113, 0xFFFFFFFF, STR_NONE }, // panel / background - { WWT_CAPTION, 0, 0, 57, 1, 14, STR_SCENERY_SCATTER, STR_WINDOW_TITLE_TIP }, // title bar - { WWT_CLOSEBOX, 0, 57, 68, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, // close x button + { WWT_FRAME, 1, 0, 85, 0, 99, 0xFFFFFFFF, STR_NONE }, // panel / background + { WWT_CAPTION, 0, 1, 84, 1, 14, STR_SCENERY_SCATTER, STR_WINDOW_TITLE_TIP }, // title bar + { WWT_CLOSEBOX, 0, 73, 83, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, // close x button - { WWT_IMGBTN, 1, 5, 48, 17, 48, SPR_LAND_TOOL_SIZE_0, STR_NONE }, // preview box - { WWT_TRNBTN, 1, 6, 23, 18, 33, IMAGE_TYPE_REMAP | SPR_LAND_TOOL_DECREASE, STR_ADJUST_SMALLER_LAND_TIP }, // decrement size - { WWT_TRNBTN, 1, 32, 49, 32, 47, IMAGE_TYPE_REMAP | SPR_LAND_TOOL_INCREASE, STR_ADJUST_LARGER_LAND_TIP }, // increment size + { WWT_IMGBTN, 1, 20, 63, 17, 48, SPR_LAND_TOOL_SIZE_0, STR_NONE }, // preview box + { WWT_TRNBTN, 1, 21, 36, 18, 33, IMAGE_TYPE_REMAP | SPR_LAND_TOOL_DECREASE, STR_ADJUST_SMALLER_LAND_TIP }, // decrement size + { WWT_TRNBTN, 1, 47, 62, 32, 47, IMAGE_TYPE_REMAP | SPR_LAND_TOOL_INCREASE, STR_ADJUST_LARGER_LAND_TIP }, // increment size - { WWT_IMGBTN, 1, 5, 48, 65, 96, 0xFFFFFFFF, STR_NONE }, // preview box - { WWT_TRNBTN, 1, 6, 23, 66, 81, IMAGE_TYPE_REMAP | SPR_LAND_TOOL_DECREASE, STR_ADJUST_SMALLER_LAND_TIP }, // decrement size amount - { WWT_TRNBTN, 1, 32, 49, 80, 94, IMAGE_TYPE_REMAP | SPR_LAND_TOOL_INCREASE, STR_ADJUST_LARGER_LAND_TIP }, // increment size amount + { WWT_GROUPBOX, 1, 3, 82, 55, 96, STR_SCATTER_TOOL_DENSITY, STR_NONE }, + { WWT_FLATBTN, 1, 7, 30, 68, 91, IMAGE_TYPE_REMAP | SPR_G2_SCENERY_SCATTER_LOW, STR_SCATTER_TOOL_DENSITY_LOW }, // low amount + { WWT_FLATBTN, 1, 31, 54, 68, 91, IMAGE_TYPE_REMAP | SPR_G2_SCENERY_SCATTER_MEDIUM, STR_SCATTER_TOOL_DENSITY_MEDIUM }, // medium amount + { WWT_FLATBTN, 1, 55, 78, 68, 91, IMAGE_TYPE_REMAP | SPR_G2_SCENERY_SCATTER_HIGH, STR_SCATTER_TOOL_DENSITY_HIGH }, // high amount { WIDGETS_END }, }; // clang-format on @@ -98,12 +98,12 @@ rct_window* window_scenery_scatter_open() if (window != nullptr) return window; - window = window_create( - ScreenCoordsXY(context_get_width() - 70, 29), 70, 114, &window_clear_scenery_events, WC_SCENERY_SCATTER, 0); + window = window_create_auto_pos(86, 100, &window_clear_scenery_events, WC_SCENERY_SCATTER, 0); + window->widgets = window_scenery_scatter_widgets; window->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_INCREMENT) | (1 << WIDX_DECREMENT) | (1 << WIDX_PREVIEW) - | (1 << WIDX_AINCREMENT) | (1 << WIDX_ADECREMENT) | (1 << WIDX_AMOUNT); - window->hold_down_widgets = (1 << WIDX_INCREMENT) | (1 << WIDX_DECREMENT) | (1 << WIDX_AINCREMENT) | (1 << WIDX_ADECREMENT); + | (1 << WIDX_DENSITY_LOW) | (1 << WIDX_DENSITY_MEDIUM) | (1 << WIDX_DENSITY_HIGH); + window->hold_down_widgets = (1 << WIDX_INCREMENT) | (1 << WIDX_DECREMENT); window_init_scroll_widgets(window); window_push_others_below(window); @@ -123,9 +123,20 @@ static void window_scenery_scatter_mouseup(rct_window* w, rct_widgetindex widget window_close(w); break; case WIDX_PREVIEW: - case WIDX_AMOUNT: window_scenery_scatter_inputsize(w, widgetIndex); break; + + case WIDX_DENSITY_LOW: + gWindowSceneryScatterDensity = ScatterToolDensity::LowDensity; + break; + + case WIDX_DENSITY_MEDIUM: + gWindowSceneryScatterDensity = ScatterToolDensity::MediumDensity; + break; + + case WIDX_DENSITY_HIGH: + gWindowSceneryScatterDensity = ScatterToolDensity::HighDensity; + break; } } @@ -144,21 +155,6 @@ static void window_scenery_scatter_mousedown(rct_window* w, rct_widgetindex widg // Increment land tool size, if it stays within the limit gWindowSceneryScatterSize = std::min(MAXIMUM_TOOL_SIZE, gWindowSceneryScatterSize + 1); - // Invalidate the window - w->Invalidate(); - break; - - case WIDX_ADECREMENT: - // Decrement land tool size, if it stays within the limit - gWindowSceneryScatterAmount = std::max(1, gWindowSceneryScatterAmount - 1); - - // Invalidate the window - w->Invalidate(); - break; - case WIDX_AINCREMENT: - // Increment land tool size, if it stays within the limit - gWindowSceneryScatterAmount = std::min(MAX_AMOUNT, gWindowSceneryScatterAmount + 1); - // Invalidate the window w->Invalidate(); break; @@ -170,7 +166,7 @@ static void window_scenery_scatter_textinput(rct_window* w, rct_widgetindex widg int32_t size; char* end; - if (!(widgetIndex == WIDX_PREVIEW || widgetIndex == WIDX_AMOUNT) || text == nullptr) + if (widgetIndex != WIDX_PREVIEW || text == nullptr) return; size = strtol(text, &end, 10); @@ -183,11 +179,6 @@ static void window_scenery_scatter_textinput(rct_window* w, rct_widgetindex widg size = std::min(MAXIMUM_TOOL_SIZE, size); gWindowSceneryScatterSize = size; break; - case WIDX_AMOUNT: - size = std::max(1, size); - size = std::min(MAX_AMOUNT, size); - gWindowSceneryScatterAmount = size; - break; } w->Invalidate(); } @@ -203,11 +194,6 @@ static void window_scenery_scatter_inputsize(rct_window* w, rct_widgetindex widg TextInputDescriptionArgs[1] = MAXIMUM_TOOL_SIZE; maxlen = 3; break; - case WIDX_AMOUNT: - TextInputDescriptionArgs[0] = 1; - TextInputDescriptionArgs[1] = MAX_AMOUNT; - maxlen = 4; // Catch 100 - break; } window_text_input_open(w, widgetindex, STR_SELECTION_SIZE, STR_ENTER_SELECTION_SIZE, STR_NONE, STR_NONE, maxlen); } @@ -220,7 +206,24 @@ static void window_scenery_scatter_update(rct_window* w) static void window_scenery_scatter_invalidate(rct_window* w) { // Set the preview image button to be pressed down - w->pressed_widgets = (1 << WIDX_PREVIEW) | (1 << WIDX_AMOUNT); + w->pressed_widgets = (1 << WIDX_PREVIEW); + + // Set density buttons' pressed state. + switch (gWindowSceneryScatterDensity) + { + case ScatterToolDensity::LowDensity: + w->pressed_widgets |= (1 << WIDX_DENSITY_LOW); + break; + + case ScatterToolDensity::MediumDensity: + w->pressed_widgets |= (1 << WIDX_DENSITY_MEDIUM); + break; + + case ScatterToolDensity::HighDensity: + w->pressed_widgets |= (1 << WIDX_DENSITY_HIGH); + break; + } + // Update the preview image (for tool sizes up to 7) window_scenery_scatter_widgets[WIDX_PREVIEW].image = land_tool_size_to_sprite_index(gWindowSceneryScatterSize); } @@ -229,25 +232,12 @@ static void window_scenery_scatter_paint(rct_window* w, rct_drawpixelinfo* dpi) { window_draw_widgets(w, dpi); - int32_t x, y; - x = w->x + window_scenery_scatter_widgets[WIDX_PREVIEW].left; - y = w->y + window_scenery_scatter_widgets[WIDX_PREVIEW].bottom + 2; - gfx_draw_string_left(dpi, STR_SMALL_SIZE, nullptr, COLOUR_BLACK, x, y); - - x = w->x + window_scenery_scatter_widgets[WIDX_AMOUNT].left; - y = w->y + window_scenery_scatter_widgets[WIDX_AMOUNT].bottom + 2; - gfx_draw_string_left(dpi, STR_SMALL_AMOUNT, nullptr, COLOUR_BLACK, x, y); - - // Draw number for tool sizes bigger than 7 - + // Draw area as a number for tool sizes bigger than 7 if (gWindowSceneryScatterSize > MAX_TOOL_SIZE_WITH_SPRITE) { - x = w->x + (window_scenery_scatter_widgets[WIDX_PREVIEW].left + window_scenery_scatter_widgets[WIDX_PREVIEW].right) / 2; - y = w->y + (window_scenery_scatter_widgets[WIDX_PREVIEW].top + window_scenery_scatter_widgets[WIDX_PREVIEW].bottom) / 2; + auto preview = window_scenery_scatter_widgets[WIDX_PREVIEW]; + int32_t x = w->x + (preview.left + preview.right) / 2; + int32_t y = w->y + (preview.top + preview.bottom) / 2; gfx_draw_string_centred(dpi, STR_LAND_TOOL_SIZE_VALUE, x, y, COLOUR_BLACK, &gWindowSceneryScatterSize); } - - x = w->x + (window_scenery_scatter_widgets[WIDX_AMOUNT].left + window_scenery_scatter_widgets[WIDX_AMOUNT].right) / 2; - y = w->y + (window_scenery_scatter_widgets[WIDX_AMOUNT].top + window_scenery_scatter_widgets[WIDX_AMOUNT].bottom) / 2; - gfx_draw_string_centred(dpi, STR_LAND_TOOL_SIZE_VALUE, x, y, COLOUR_BLACK, &gWindowSceneryScatterAmount); } diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 2b11743396..ab669cb158 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -1761,14 +1761,27 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo bool isCluster = gWindowSceneryScatterEnabled && (network_get_mode() != NETWORK_MODE_CLIENT || network_can_perform_command(network_get_current_player_group_index(), -2)); + if (isCluster) { - quantity = gWindowSceneryScatterAmount; + switch (gWindowSceneryScatterDensity) + { + case ScatterToolDensity::LowDensity: + quantity = gWindowSceneryScatterSize; + break; + + case ScatterToolDensity::MediumDensity: + quantity = gWindowSceneryScatterSize * 2; + break; + + case ScatterToolDensity::HighDensity: + quantity = gWindowSceneryScatterSize * 3; + break; + } } bool forceError = true; - uint16_t retry = 0; - for (int32_t q = 0; q < quantity + retry; q++) + for (int32_t q = 0; q < quantity; q++) { int32_t zCoordinate = gSceneryPlaceZ; rct_scenery_entry* scenery = get_small_scenery_entry((parameter_1 >> 8) & 0xFF); @@ -1859,11 +1872,6 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo break; } } - else - { - if (retry < gWindowSceneryScatterSize * gWindowSceneryScatterSize) - retry++; - } gSceneryPlaceZ = zCoordinate; } break; diff --git a/src/openrct2-ui/windows/Window.h b/src/openrct2-ui/windows/Window.h index 0e16acd044..2dfcc24809 100644 --- a/src/openrct2-ui/windows/Window.h +++ b/src/openrct2-ui/windows/Window.h @@ -19,12 +19,13 @@ using scenarioselect_callback = void (*)(const utf8* path); struct Peep; struct TileElement; struct Vehicle; +enum class ScatterToolDensity : uint8_t; extern uint16_t gWindowSceneryTabSelections[]; extern uint8_t gWindowSceneryActiveTabIndex; extern rct_window* gWindowSceneryScatterWindow; extern uint16_t gWindowSceneryScatterSize; -extern uint16_t gWindowSceneryScatterAmount; +extern ScatterToolDensity gWindowSceneryScatterDensity; extern bool gWindowSceneryScatterEnabled; extern uint8_t gWindowSceneryPaintEnabled; extern uint8_t gWindowSceneryRotation; diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index bae72e358d..2db5ca07bf 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3897,9 +3897,11 @@ enum STR_OPTIONS_RANDOM_TITLE_SEQUENCE = 6349, STR_SCENERY_SCATTER = 6350, - STR_SMALL_SIZE = 6351, - STR_SMALL_AMOUNT = 6352, - STR_THEMES_WINDOW_SCENERY_SCATTER = 6353, + STR_THEMES_WINDOW_SCENERY_SCATTER = 6351, + STR_SCATTER_TOOL_DENSITY = 6352, + STR_SCATTER_TOOL_DENSITY_LOW = 6353, + STR_SCATTER_TOOL_DENSITY_MEDIUM = 6354, + STR_SCATTER_TOOL_DENSITY_HIGH = 6355, // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index c1f0880b6b..77c1212587 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -857,7 +857,11 @@ enum SPR_G2_MOUNTAIN_TOOL_EVEN = SPR_G2_BEGIN + 132, SPR_G2_MOUNTAIN_TOOL_ODD = SPR_G2_BEGIN + 133, - SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 134, + SPR_G2_SCENERY_SCATTER_LOW = SPR_G2_BEGIN + 134, + SPR_G2_SCENERY_SCATTER_MEDIUM = SPR_G2_BEGIN + 135, + SPR_G2_SCENERY_SCATTER_HIGH = SPR_G2_BEGIN + 136, + + SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 137, SPR_G2_AE_UPPER = SPR_G2_CHAR_BEGIN, SPR_G2_AE_LOWER = SPR_G2_CHAR_BEGIN + 1, diff --git a/src/openrct2/world/Scenery.h b/src/openrct2/world/Scenery.h index 5860950a6d..ead02fd7a3 100644 --- a/src/openrct2/world/Scenery.h +++ b/src/openrct2/world/Scenery.h @@ -243,6 +243,13 @@ enum BANNER_ENTRY_FLAG_HAS_PRIMARY_COLOUR = (1 << 0), }; +enum class ScatterToolDensity : uint8_t +{ + LowDensity, + MediumDensity, + HighDensity +}; + #define SCENERY_ENTRIES_BY_TAB 1024 constexpr auto WINDOW_SCENERY_TAB_SELECTION_UNDEFINED = std::numeric_limits::max();