From 6429ccd9df3472c52f8cf5ae8e79b2bc475427d2 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 13 Mar 2017 19:27:20 +0000 Subject: [PATCH] Implement scenery eye dropper --- src/openrct2/windows/scenery.c | 41 +++++++++++++- src/openrct2/windows/top_toolbar.c | 88 +++++++++++++++++++++++++++++- src/openrct2/world/scenery.c | 12 ++++ src/openrct2/world/scenery.h | 2 + 4 files changed, 138 insertions(+), 5 deletions(-) diff --git a/src/openrct2/windows/scenery.c b/src/openrct2/windows/scenery.c index 621571c622..ea2e6975d9 100644 --- a/src/openrct2/windows/scenery.c +++ b/src/openrct2/windows/scenery.c @@ -926,8 +926,8 @@ void window_scenery_invalidate(rct_window *w) window_scenery_widgets[WIDX_SCENERY_TITLE].text = titleStringId; - w->pressed_widgets = (((uint32)w->pressed_widgets & 0xFF00000F) | (1 << (tabIndex + 4))) & 0xBBFFFFFF; - + w->pressed_widgets = 0; + w->pressed_widgets |= 1ULL << (tabIndex + 4); if (gWindowSceneryPaintEnabled == 1) w->pressed_widgets |= (1 << WIDX_SCENERY_REPAINT_SCENERY_BUTTON); if (gWindowSceneryEyedropperEnabled) @@ -939,11 +939,14 @@ void window_scenery_invalidate(rct_window *w) window_scenery_widgets[WIDX_SCENERY_EYEDROPPER_BUTTON].type = WWT_EMPTY; window_scenery_widgets[WIDX_SCENERY_BUILD_CLUSTER_BUTTON].type = WWT_EMPTY; + if (!(gWindowSceneryPaintEnabled & 1)) { + window_scenery_widgets[WIDX_SCENERY_EYEDROPPER_BUTTON].type = WWT_FLATBTN; + } + sint16 tabSelectedSceneryId = gWindowSceneryTabSelections[tabIndex]; if (tabSelectedSceneryId != -1) { if (tabSelectedSceneryId < 0x100) { if (!(gWindowSceneryPaintEnabled & 1)) { - window_scenery_widgets[WIDX_SCENERY_EYEDROPPER_BUTTON].type = WWT_FLATBTN; window_scenery_widgets[WIDX_SCENERY_BUILD_CLUSTER_BUTTON].type = WWT_FLATBTN; } @@ -1245,3 +1248,35 @@ void window_scenery_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 sc sceneryTabItemIndex++; } } + +static sint32 window_scenery_find_tab_with_scenery_id(sint32 sceneryId) +{ + for (sint32 i = 0; i < 20; i++) { + for (sint32 j = 0; j < SCENERY_ENTRIES_BY_TAB; j++) { + sint16 entry = window_scenery_tab_entries[i][j]; + if (entry == -1) break; + if (entry == sceneryId) return i; + } + } + return -1; +} + +bool window_scenery_set_selected_item(sint32 sceneryId) +{ + bool result = false; + rct_window * w = window_bring_to_front_by_class(WC_SCENERY); + if (w != NULL) { + sint32 tabIndex = window_scenery_find_tab_with_scenery_id(sceneryId); + if (tabIndex != -1) { + gWindowSceneryActiveTabIndex = tabIndex; + gWindowSceneryTabSelections[tabIndex] = sceneryId; + + audio_play_sound_panned(4, (w->width >> 1) + w->x, 0, 0, 0); + w->scenery.hover_counter = -16; + gSceneryPlaceCost = MONEY32_UNDEFINED; + window_invalidate(w); + result = true; + } + } + return result; +} diff --git a/src/openrct2/windows/top_toolbar.c b/src/openrct2/windows/top_toolbar.c index c004e76ed7..a27c7582e1 100644 --- a/src/openrct2/windows/top_toolbar.c +++ b/src/openrct2/windows/top_toolbar.c @@ -35,6 +35,7 @@ #include "../title/TitleScreen.h" #include "../util/util.h" #include "../world/banner.h" +#include "../world/footpath.h" #include "../world/scenery.h" #include "dropdown.h" @@ -1002,16 +1003,99 @@ static void repaint_scenery_tool_down(sint16 x, sint16 y, sint16 widgetIndex){ static void scenery_eyedropper_tool_down(sint16 x, sint16 y, sint16 widgetIndex) { + uint16 flags = + VIEWPORT_INTERACTION_MASK_SCENERY & + VIEWPORT_INTERACTION_MASK_WALL & + VIEWPORT_INTERACTION_MASK_LARGE_SCENERY & + VIEWPORT_INTERACTION_MASK_BANNER & + VIEWPORT_INTERACTION_MASK_FOOTPATH_ITEM; + sint16 gridX, gridY; + sint32 type; + rct_map_element* mapElement; + rct_viewport * viewport; + get_map_coordinates_from_pos(x, y, flags, &gridX, &gridY, &type, &mapElement, &viewport); + + switch (type) { + case VIEWPORT_INTERACTION_ITEM_SCENERY: + { + sint32 entryIndex = mapElement->properties.scenery.type; + rct_scenery_entry * sceneryEntry = get_small_scenery_entry(entryIndex); + if (sceneryEntry != NULL || sceneryEntry != (rct_scenery_entry *)-1) { + sint32 sceneryId = get_scenery_id_from_entry_index(OBJECT_TYPE_SMALL_SCENERY, entryIndex); + if (sceneryId != -1 && window_scenery_set_selected_item(sceneryId)) { + gWindowSceneryRotation = map_element_get_direction(mapElement); + gWindowSceneryPrimaryColour = mapElement->properties.scenery.colour_1 & 0x1F; + gWindowScenerySecondaryColour = mapElement->properties.scenery.colour_2 & 0x1F; + gWindowSceneryEyedropperEnabled = false; + } + } + break; + } + case VIEWPORT_INTERACTION_ITEM_WALL: + { + sint32 entryIndex = mapElement->properties.wall.type; + rct_scenery_entry * sceneryEntry = get_wall_entry(entryIndex); + if (sceneryEntry != NULL || sceneryEntry != (rct_scenery_entry *)-1) { + sint32 sceneryId = get_scenery_id_from_entry_index(OBJECT_TYPE_WALLS, entryIndex); + if (sceneryId != -1 && window_scenery_set_selected_item(sceneryId)) { + gWindowSceneryPrimaryColour = mapElement->properties.wall.colour_1 & 0x1F; + gWindowScenerySecondaryColour = wall_element_get_secondary_colour(mapElement); + gWindowSceneryTertiaryColour = mapElement->properties.wall.colour_3 & 0x1F; + gWindowSceneryEyedropperEnabled = false; + } + } + break; + } + case VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY: + { + sint32 entryIndex = mapElement->properties.scenerymultiple.type; + rct_scenery_entry * sceneryEntry = get_large_scenery_entry(entryIndex); + if (sceneryEntry != NULL || sceneryEntry != (rct_scenery_entry *)-1) { + sint32 sceneryId = get_scenery_id_from_entry_index(OBJECT_TYPE_LARGE_SCENERY, entryIndex); + if (sceneryId != -1 && window_scenery_set_selected_item(sceneryId)) { + gWindowSceneryRotation = map_element_get_direction(mapElement); + gWindowSceneryPrimaryColour = mapElement->properties.scenerymultiple.colour[0] & 0x1F; + gWindowScenerySecondaryColour = mapElement->properties.scenerymultiple.colour[1] & 0x1F; + gWindowSceneryEyedropperEnabled = false; + } + } + break; + } + case VIEWPORT_INTERACTION_ITEM_BANNER: + { + sint32 entryIndex = mapElement->properties.banner.index; + rct_scenery_entry * sceneryEntry = get_large_scenery_entry(entryIndex); + if (sceneryEntry != NULL || sceneryEntry != (rct_scenery_entry *)-1) { + sint32 sceneryId = get_scenery_id_from_entry_index(OBJECT_TYPE_BANNERS, entryIndex); + if (sceneryId != -1 && window_scenery_set_selected_item(sceneryId)) { + gWindowSceneryEyedropperEnabled = false; + } + } + break; + } + case VIEWPORT_INTERACTION_ITEM_FOOTPATH_ITEM: + { + sint32 entryIndex = footpath_element_get_path_scenery_index(mapElement); + rct_scenery_entry * sceneryEntry = get_footpath_item_entry(entryIndex); + if (sceneryEntry != NULL || sceneryEntry != (rct_scenery_entry *)-1) { + sint32 sceneryId = get_scenery_id_from_entry_index(OBJECT_TYPE_PATH_BITS, entryIndex); + if (sceneryId != -1 && window_scenery_set_selected_item(sceneryId)) { + gWindowSceneryEyedropperEnabled = false; + } + } + break; + } + } } /** * * rct2: 0x006E1F34 * Outputs - * eax : grid_x + * eax : gridX * ebx : parameter_1 - * ecx : grid_y + * ecx : gridY * edx : parameter_2 * edi : parameter_3 */ diff --git a/src/openrct2/world/scenery.c b/src/openrct2/world/scenery.c index 9c22faf927..a9fe9d7f68 100644 --- a/src/openrct2/world/scenery.c +++ b/src/openrct2/world/scenery.c @@ -288,3 +288,15 @@ rct_scenery_set_entry *get_scenery_group_entry(sint32 entryIndex) } return (rct_scenery_set_entry*)gSceneryGroupEntries[entryIndex]; } + +sint32 get_scenery_id_from_entry_index(uint8 objectType, sint32 entryIndex) +{ + switch (objectType) { + case OBJECT_TYPE_SMALL_SCENERY: return entryIndex; + case OBJECT_TYPE_PATH_BITS: return entryIndex + 0x100; + case OBJECT_TYPE_WALLS: return entryIndex + 0x200; + case OBJECT_TYPE_LARGE_SCENERY: return entryIndex + 0x300; + case OBJECT_TYPE_BANNERS: return entryIndex + 0x400; + default: return -1; + } +} diff --git a/src/openrct2/world/scenery.h b/src/openrct2/world/scenery.h index 5a9dbf7d03..ade4c9e8a9 100644 --- a/src/openrct2/world/scenery.h +++ b/src/openrct2/world/scenery.h @@ -273,6 +273,7 @@ void scenery_update_tile(sint32 x, sint32 y); void scenery_update_age(sint32 x, sint32 y, rct_map_element *mapElement); void scenery_set_default_placement_configuration(); void scenery_remove_ghost_tool_placement(); +bool window_scenery_set_selected_item(sint32 sceneryId); rct_scenery_entry *get_small_scenery_entry(sint32 entryIndex); rct_scenery_entry *get_large_scenery_entry(sint32 entryIndex); @@ -281,5 +282,6 @@ rct_scenery_entry *get_banner_entry(sint32 entryIndex); rct_scenery_entry *get_footpath_item_entry(sint32 entryIndex); rct_scenery_set_entry *get_scenery_group_entry(sint32 entryIndex); +sint32 get_scenery_id_from_entry_index(uint8 objectType, sint32 entryIndex); #endif