Introduce low, medium, and high density buttons to the scatter tool.

Change window lay-out to more closely resemble others by introducing
density buttons, along with new sprites.

The amount of elements varies by density as follows:
* Low: number of elements equal to tool size
* Medium: twice as many elements as the tool size
* High: three times as many elements as the tool size.

Remove extraneous 'retry' clause.
This commit is contained in:
Aaron van Geffen 2020-02-19 14:05:36 +01:00
parent 642de8d11a
commit 2528e94b48
12 changed files with 104 additions and 81 deletions

View File

@ -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 #

View File

@ -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,

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -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;

View File

@ -15,8 +15,6 @@
#include <openrct2/localisation/Localisation.h>
#include <openrct2/world/Scenery.h>
#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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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<uint16_t>::max();