From 09cc46c1e6fabd2daab1d8b8a5ff60ff17aa805c Mon Sep 17 00:00:00 2001 From: Robert Jordan Date: Fri, 15 May 2015 11:28:27 -0400 Subject: [PATCH] Almost finished land rights tool --- data/language/english_uk.txt | 4 + projects/openrct2.vcxproj | 1 + projects/openrct2.vcxproj.filters | 4 +- src/game.c | 4 +- src/interface/window.h | 4 +- src/scenario.h | 2 + src/windows/land_rights.c | 293 ++++++++++++++++++ src/windows/park.c | 484 +++++++++++++++++++++++++++++- src/windows/top_toolbar.c | 123 ++++++++ src/world/map.c | 1 + src/world/map.h | 2 + 11 files changed, 914 insertions(+), 8 deletions(-) create mode 100644 src/windows/land_rights.c diff --git a/data/language/english_uk.txt b/data/language/english_uk.txt index 1da3f3d858..0e4a0e2223 100644 --- a/data/language/english_uk.txt +++ b/data/language/english_uk.txt @@ -3465,3 +3465,7 @@ STR_5128 :Selection size STR_5129 :Enter selection size between {COMMA16} and {COMMA16} STR_5130 :Map size STR_5131 :Enter map size between {COMMA16} and {COMMA16} +STR_5132 :Land rights +STR_5133 :{SMALLFONT}{BLACK}Adjust smaller area of land rights +STR_5134 :{SMALLFONT}{BLACK}Adjust larger area of land rights +STR_5135 :Buy land rights \ No newline at end of file diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index 1f3deaaf20..18c7dfc1dd 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -96,6 +96,7 @@ + diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index 68fc0779b8..0d27fea1b5 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -366,7 +366,6 @@ Source\World - Source @@ -434,6 +433,9 @@ Source\Windows + + Source\Windows + diff --git a/src/game.c b/src/game.c index 8d1f6a2473..01d0760d14 100644 --- a/src/game.c +++ b/src/game.c @@ -909,7 +909,7 @@ static uint32 game_do_command_table[58] = { 0, 0, 0, - 0x006649BD, + 0,//0x006649BD, //buy_land_rights 0x006666E7, 0, 0x006CD8CE, @@ -972,7 +972,7 @@ static GAME_COMMAND_POINTER* new_game_command_table[58] = { game_command_set_staff_order, game_command_set_park_name, game_command_set_park_open, - game_command_emptysub, + game_command_buy_land_rights, //game_command_emptysub,//game_command_buy_land_rights, game_command_emptysub, game_command_remove_park_entrance, game_command_emptysub, diff --git a/src/interface/window.h b/src/interface/window.h index 459b8ddf4b..246d4ba793 100644 --- a/src/interface/window.h +++ b/src/interface/window.h @@ -403,7 +403,8 @@ enum { WC_MAPGEN = 114, WC_LOADSAVE = 115, WC_LOADSAVE_OVERWRITE_PROMPT = 116, - WC_TITLE_OPTIONS = 117 + WC_TITLE_OPTIONS = 117, + WC_LAND_RIGHTS = 118 } WINDOW_CLASS; enum PROMPT_MODE { @@ -516,6 +517,7 @@ void window_track_list_open(ride_list_item item); void window_clear_scenery_open(); void window_land_open(); void window_water_open(); +void window_land_rights_open(); void window_staff_list_open(); void window_guest_list_open(); void window_guest_list_open_with_filter(int type, int index); diff --git a/src/scenario.h b/src/scenario.h index 91eb1caeef..d1cc3cb9ed 100644 --- a/src/scenario.h +++ b/src/scenario.h @@ -415,4 +415,6 @@ void scenario_failure(); void scenario_success(); void scenario_success_submit_name(const char *name); +void game_command_buy_land_rights(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); + #endif diff --git a/src/windows/land_rights.c b/src/windows/land_rights.c new file mode 100644 index 0000000000..5bf2256b0c --- /dev/null +++ b/src/windows/land_rights.c @@ -0,0 +1,293 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of OpenRCT2. + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "../addresses.h" +#include "../input.h" +#include "../interface/widget.h" +#include "../interface/window.h" +#include "../interface/viewport.h" +#include "../localisation/localisation.h" +#include "../sprites.h" +#include "../world/map.h" + +const int MAX_LAND_RIGHTS_SIZE = 7; + +enum WINDOW_WATER_WIDGET_IDX { + WIDX_BACKGROUND, + WIDX_TITLE, + WIDX_CLOSE, + WIDX_PREVIEW, + WIDX_DECREMENT, + WIDX_INCREMENT, + WIDX_BUY_LAND_RIGHTS, + WIDX_BUY_CONSTRUCTION_RIGHTS +}; + +static rct_widget window_land_rights_widgets[] = { + { WWT_FRAME, 0, 0, 97, 0, 93, -1, STR_NONE }, // panel / background + { WWT_CAPTION, 0, 1, 96, 1, 14, 5132, STR_WINDOW_TITLE_TIP }, // title bar + { WWT_CLOSEBOX, 0, 85, 95, 2, 13, 824, STR_CLOSE_WINDOW_TIP }, // close x button + { WWT_IMGBTN, 0, 27, 70, 17, 48, SPR_LAND_TOOL_SIZE_0, STR_NONE }, // preview box + { WWT_TRNBTN, 2, 28, 43, 18, 33, 0x20000000 | SPR_LAND_TOOL_DECREASE, 5133 }, // decrement size + { WWT_TRNBTN, 2, 54, 69, 32, 47, 0x20000000 | SPR_LAND_TOOL_INCREASE, 5134 }, // increment size + { WWT_FLATBTN, 2, 22, 45, 53, 76, 0x20000000 | SPR_BUY_LAND_RIGHTS, 5135 }, // land rights + { WWT_FLATBTN, 2, 52, 75, 53, 76, 0x20000000 | SPR_BUY_CONSTRUCTION_RIGHTS, 5136 }, // construction rights + { WIDGETS_END }, +}; + +static int window_land_rights_should_close(); + +static void window_land_rights_emptysub() { } +static void window_land_rights_close(); +static void window_land_rights_mouseup(); +static void window_land_rights_update(); +static void window_land_rights_invalidate(); +static void window_land_rights_paint(); +static void window_land_rights_textinput(); +static void window_land_rights_inputsize(rct_window *w); + +static void* window_land_rights_events[] = { + window_land_rights_close, + window_land_rights_mouseup, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_update, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_textinput, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_emptysub, + window_land_rights_invalidate, + window_land_rights_paint, + window_land_rights_emptysub +}; + +void window_land_rights_open() +{ + rct_window* window; + + // Check if window is already open + if (window_find_by_class(WC_LAND_RIGHTS) != NULL) + return; + + window = window_create(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) - 98, 29, 98, 94, (uint32*)window_land_rights_events, WC_LAND_RIGHTS, 0); + window->widgets = window_land_rights_widgets; + window->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_DECREMENT) | (1 << WIDX_INCREMENT) | (1 << WIDX_PREVIEW) | + (1 << WIDX_BUY_LAND_RIGHTS) | (1 << WIDX_BUY_CONSTRUCTION_RIGHTS); + window_init_scroll_widgets(window); + window_push_others_below(window); + + LandRightsMode = true; + window->pressed_widgets = (1 << WIDX_BUY_LAND_RIGHTS); + + RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, uint32) = MONEY32_UNDEFINED; + RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, uint32) = MONEY32_UNDEFINED; + window->colours[0] = 19; + window->colours[1] = 19; + window->colours[2] = 19; + + show_land_rights(); + show_gridlines(); +} + +static void window_land_rights_close() +{ + if (LandRightsMode) + hide_land_rights(); + else + hide_construction_rights(); + // If the tool wasn't changed, turn tool off + if (!window_land_rights_should_close()) + tool_cancel(); +} + +static void window_land_rights_mouseup() +{ + rct_window *w; + int limit; + short widgetIndex; + + window_widget_get_registers(w, widgetIndex); + + switch (widgetIndex) { + case WIDX_CLOSE: + window_close(w); + break; + case WIDX_DECREMENT: + // Decrement land tool size + RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16)--; + limit = 1; + if (RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) < limit) + RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = limit; + + // Invalidate the window + window_invalidate(w); + break; + case WIDX_INCREMENT: + // Increment land tool size + RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16)++; + + limit = MAX_LAND_RIGHTS_SIZE; + + if (RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) > limit) + RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = limit; + + // Invalidate the window + window_invalidate(w); + break; + case WIDX_PREVIEW: + window_land_rights_inputsize(w); + break; + case WIDX_BUY_LAND_RIGHTS: + if (!LandRightsMode) { + LandRightsMode = true; + hide_construction_rights(); + show_land_rights(); + window_invalidate(w); + } + //RCT2_CALLPROC_X(0x006682F7, 0, 0, 0, widgetIndex, (int)w, 0, 0); + break; + case WIDX_BUY_CONSTRUCTION_RIGHTS: + if (LandRightsMode) { + LandRightsMode = false; + hide_land_rights(); + show_construction_rights(); + window_invalidate(w); + } + //RCT2_CALLPROC_X(0x00668393, 0, 0, 0, widgetIndex, (int)w, 0, 0); + break; + } +} + +static void window_land_rights_textinput() +{ + uint8 result; + short widgetIndex; + rct_window *w; + char *text; + int size; + char* end; + + window_textinput_get_registers(w, widgetIndex, result, text); + + if (widgetIndex != WIDX_PREVIEW || !result) + return; + + size = strtol(text, &end, 10); + if (*end == '\0') { + if (size < 1) size = 1; + if (size > MAX_LAND_RIGHTS_SIZE) size = MAX_LAND_RIGHTS_SIZE; + RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = size; + window_invalidate(w); + } +} + +static void window_land_rights_inputsize(rct_window *w) +{ + ((uint16*)TextInputDescriptionArgs)[0] = 1; + ((uint16*)TextInputDescriptionArgs)[1] = MAX_LAND_RIGHTS_SIZE; + window_text_input_open(w, WIDX_PREVIEW, 5128, 5130, STR_NONE, STR_NONE, 3); +} + +static void window_land_rights_update(rct_window *w) +{ + // Close window if another tool is open + if (window_land_rights_should_close()) + window_close(w); +} + +static void window_land_rights_invalidate() +{ + rct_window *w; + + window_get_register(w); + + // Set the preview image button to be pressed down + w->pressed_widgets |= (1 << WIDX_PREVIEW) | (1 << (LandRightsMode ? WIDX_BUY_LAND_RIGHTS : WIDX_BUY_CONSTRUCTION_RIGHTS)); + w->pressed_widgets &= ~(1 << (!LandRightsMode ? WIDX_BUY_LAND_RIGHTS : WIDX_BUY_CONSTRUCTION_RIGHTS)); + + + // Update the preview image + //window_water_widgets[WIDX_PREVIEW].image = SPR_LAND_TOOL_SIZE_0 + RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16); + + window_land_rights_widgets[WIDX_PREVIEW].image = RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) <= 7 ? + SPR_LAND_TOOL_SIZE_0 + RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) : + 0xFFFFFFFF; + +} + +static void window_land_rights_paint() +{ + rct_window *w; + rct_drawpixelinfo *dpi; + int x, y; + + window_paint_get_registers(w, dpi); + + x = w->x + (window_land_rights_widgets[WIDX_PREVIEW].left + window_land_rights_widgets[WIDX_PREVIEW].right) / 2; + y = w->y + (window_land_rights_widgets[WIDX_PREVIEW].top + window_land_rights_widgets[WIDX_PREVIEW].bottom) / 2; + + window_draw_widgets(w, dpi); + // FEATURE larger land tool size support + if (RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) > 7) { + RCT2_GLOBAL(0x009BC677, char) = FORMAT_BLACK; + RCT2_GLOBAL(0x009BC678, char) = FORMAT_COMMA16; + RCT2_GLOBAL(0x009BC679, char) = 0; + RCT2_GLOBAL(0x013CE952, sint16) = RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16); + gfx_draw_string_centred(dpi, 3165, x, y - 2, 0, (void*)0x013CE952); + } + y = w->y + window_land_rights_widgets[WIDX_PREVIEW].bottom + 5; + + // Draw cost amount + x = (window_land_rights_widgets[WIDX_PREVIEW].left + window_land_rights_widgets[WIDX_PREVIEW].right) / 2 + w->x; + y = window_land_rights_widgets[WIDX_PREVIEW].bottom + w->y + 32; + if (RCT2_GLOBAL(0x00F1AD62, uint32) != MONEY32_UNDEFINED && RCT2_GLOBAL(0x00F1AD62, uint32) != 0) + gfx_draw_string_centred(dpi, 986, x, y, 0, (void*)0x00F1AD62); +} + +/** + * + * rct2: 0x0066D125 + */ +static int window_land_rights_should_close() +{ + if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)) + return 1; + if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_TOP_TOOLBAR) + return 1; + if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) != 14) + return 1; + return 0; +} diff --git a/src/windows/park.c b/src/windows/park.c index 9f3bc15bbe..94e5a5df55 100644 --- a/src/windows/park.c +++ b/src/windows/park.c @@ -36,6 +36,7 @@ #include "../util/util.h" #include "../world/park.h" #include "../world/sprite.h" +#include "../management/finance.h" #include "dropdown.h" enum WINDOW_PARK_PAGE { @@ -703,10 +704,10 @@ static void window_park_entrance_mouseup() window_park_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_BUY_LAND_RIGHTS: - RCT2_CALLPROC_X(0x006682F7, 0, 0, 0, widgetIndex, (int)w, 0, 0); + //RCT2_CALLPROC_X(0x006682F7, 0, 0, 0, widgetIndex, (int)w, 0, 0); break; case WIDX_BUY_CONSTRUCTION_RIGHTS: - RCT2_CALLPROC_X(0x00668393, 0, 0, 0, widgetIndex, (int)w, 0, 0); + //RCT2_CALLPROC_X(0x00668393, 0, 0, 0, widgetIndex, (int)w, 0, 0); break; case WIDX_LOCATE: window_scroll_to_viewport(w); @@ -836,7 +837,461 @@ static void window_park_entrance_tooldown() window_tool_get_registers(w, widgetIndex, x, y); - RCT2_CALLPROC_X(0x006681E6, x, y, 0, widgetIndex, (int)w, 0, 0); + //RCT2_CALLPROC_X(0x006681E6, x, y, 0, widgetIndex, (int)w, 0, 0); + switch (widgetIndex) { + case WIDX_BUY_LAND_RIGHTS: + screen_pos_to_map_pos(&x, &y, NULL); + if (x != (sint16)0x8000) { + RCT2_GLOBAL(0x00141E9AE, rct_string_id) = 0x6BD; + // I doubt the low byte of dx is required but its not cleared from earlier so copy in the widgetIndex + game_do_command(x, 1, y, 0x00E, 35, 0, 0); + /*int eax = x; + int ebx = 1; + int ecx = y; + int edx = 0x00E; + + RCT2_GLOBAL(0x009E32DC, uint32) = ebx; + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = 0xFFFF; + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16)) { + uint16 x1 = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16); + + while (x1 < RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16)) { + uint16 y1 = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16); + + while (y1 < RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16)) { + map_invalidate_tile_full(x1, y1); + + y1 += 0x20; + } + x1 += 0x20; + } + }*/ + } + break; + case WIDX_BUY_CONSTRUCTION_RIGHTS: + screen_pos_to_map_pos(&x, &y, NULL); + if (x != (sint16)0x8000) { + RCT2_GLOBAL(0x00141E9AE, rct_string_id) = 0x6C0; + game_do_command(x, 1, y, 0x20F, 35, 0, 0); + } + } +} + +/*enum { + OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED = (1 << 4), 0x10 + OWNERSHIP_OWNED = (1 << 5), 0x20 + OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE = (1 << 6), 0x40 + OWNERSHIP_AVAILABLE = (1 << 7) 0x80 +};*/ + +void sub_664D05_(int x, int y) +{ + RCT2_CALLPROC_X(0x00664D05, x, 0, y, 0, 0, 0, 0); +} + +int map_buy_land_rights_for_tile(int x, int y, int setting, int flags) { + int y2; + int cost; + int tile_idx; + + y2 = y; + cost = 0; + tile_idx = (((y & 0xFFE0) * 256) + (x & 0xFFE0)) / 32; + while ((TILE_MAP_ELEMENT_POINTER(tile_idx)->type & 0x3C) != 0) { + y2 += 8; + tile_idx = (((y2 & 0xFFE0) * 256) + (x & 0xFFE0)) / 32; + } + uint8 ownership = TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership; + switch (setting) { + case 0: + if ((ownership & OWNERSHIP_OWNED) != 0) { // If the land is already owned + cost = 0; + return cost; + } + else if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) != 0 || (ownership & OWNERSHIP_AVAILABLE) == 0) { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 1726; // Land not for sale! + cost = 0;// MONEY32_UNDEFINED; + return cost; + } + else { + if ((flags & 1) != 0) { + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership |= OWNERSHIP_OWNED; + sub_664D05_(x, y); + sub_664D05_(x - 32, y); + sub_664D05_(x + 32, y); + sub_664D05_(x, y + 32); + sub_664D05_(x, y - 32); + } + cost = RCT2_GLOBAL(RCT2_ADDRESS_LAND_COST, uint16); + return cost; + } + break; + case 1: + if ((flags & 1) != 0) { + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership &= 0xCF; + sub_664D05_(x, y); + sub_664D05_(x - 32, y); + sub_664D05_(x + 32, y); + sub_664D05_(x, y + 32); + sub_664D05_(x, y - 32); + } + cost = 0; + break; + case 2: + if ((ownership & (OWNERSHIP_OWNED | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)) != 0) { // If the land or construction rights are already owned + cost = 0; + return cost; + } + else if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) != 0 || (ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE) == 0) { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 1727; // Construction rights not for sale! + cost = 0;// MONEY32_UNDEFINED; + return cost; + } + else { + if ((flags & 1) != 0) { + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership |= OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED; + uint16 baseHeight = TILE_MAP_ELEMENT_POINTER(tile_idx)->base_height; + baseHeight *= 8; + sub_6EC847(x, y, baseHeight, baseHeight + 16); + } + cost = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCTION_RIGHTS_COST, uint16); + return cost; + } + break; + case 3: + if ((flags & 1) != 0) { + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership &= 0xEF; + uint16 baseHeight = TILE_MAP_ELEMENT_POINTER(tile_idx)->base_height; + baseHeight *= 8; + sub_6EC847(x, y, baseHeight, baseHeight + 16); + } + cost = 0; + break; + break; + case 4: + if ((flags & 1) != 0) { + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership |= OWNERSHIP_AVAILABLE; + uint16 baseHeight = TILE_MAP_ELEMENT_POINTER(tile_idx)->base_height; + baseHeight *= 8; + sub_6EC847(x, y, baseHeight, baseHeight + 16); + } + cost = 0; + break; + case 5: + if ((flags & 1) != 0) { + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership |= OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE; + uint16 baseHeight = TILE_MAP_ELEMENT_POINTER(tile_idx)->base_height; + baseHeight *= 8; + sub_6EC847(x, y, baseHeight, baseHeight + 16); + } + cost = 0; + break; + default: + if (x <= 32) { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 3215; + cost = 0;// MONEY32_UNDEFINED; + return cost; + } + else if (y <= 32) { + int ebp = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_UNITS, uint16); + ebp -= 32; + if (x >= ebp || y >= ebp) { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 3215; + cost = 0;// MONEY32_UNDEFINED; + return cost; + } + else { + int tile_idx2 = (((y & 0xFFE0) * 256) + (x & 0xFFE0)) / 32; + ownership = TILE_MAP_ELEMENT_POINTER(tile_idx2)->properties.surface.ownership; + y2 = y; + do { + y2 += 8; + tile_idx2 = (((y2 & 0xFFE0) * 256) + (x & 0xFFE0)) / 32; + if ((TILE_MAP_ELEMENT_POINTER(tile_idx2)->type & 0x3C) == 0x10) { + cost = 0; + return cost; + } + + } while ((TILE_MAP_ELEMENT_POINTER(((((y - 8) & 0xFFE0) * 256) + (x & 0xFFE0)) / 32)->flags & 0x80) == 0); + + uint8 bh = (flags & 0xFF00) >> 4; + if (bh == (TILE_MAP_ELEMENT_POINTER(tile_idx2)->properties.surface.ownership & 0xF0)) { + cost = 0; + return cost; + } + else { + if ((cost & 1) == 0) { + cost = RCT2_GLOBAL(RCT2_ADDRESS_LAND_COST, uint16); + return cost; + } + if ((bh & 0xF0) == 0) { + uint16 bp = RCT2_GLOBAL(RCT2_ADDRESS_PEEP_SPAWNS, uint16); + if (x != (bp & 0xFFE0)) { + bp = RCT2_GLOBAL(RCT2_ADDRESS_PEEP_SPAWNS + 2, uint16); + if (y != (bp & 0xFFE0)) { + RCT2_GLOBAL(RCT2_ADDRESS_PEEP_SPAWNS, uint16) = 0xFFFF; + } + } + bp = RCT2_GLOBAL(0x13573F8, uint16); + if (x != (bp & 0xFFE0)) { + bp = RCT2_GLOBAL(0x13573F8 + 2, uint16); + if (y != (bp & 0xFFE0)) { + RCT2_GLOBAL(0x13573F8, uint16) = 0xFFFF; + } + } + } + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership &= 0x0F; + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership |= bh; + sub_664D05_(x, y); + sub_664D05_(x - 32, y); + sub_664D05_(x + 32, y); + sub_664D05_(x, y + 32); + sub_664D05_(x, y - 32); + RCT2_GLOBAL(0x9E2E28, uint8) |= 1; + + cost = 0; + return cost; + } + } + } + break; + } + return cost; +} + +int map_buy_land_rights(int x0, int y0, int x1, int y1, int setting, int flags) +{ + int x, y, z; + money32 totalCost, cost; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_LAND_PURCHASE * 4; + + x = (x0 + x1) / 2 + 16; + y = (y0 + y1) / 2 + 16; + z = map_element_height(x, y); + RCT2_GLOBAL(0x009DEA5E, uint16) = x; + RCT2_GLOBAL(0x009DEA60, uint16) = y; + RCT2_GLOBAL(0x009DEA62, uint16) = z; + + /*x0 = clamp(0, x0, 255); + y0 = clamp(0, y0, 255); + x1 = clamp(0, x1, 255); + y1 = clamp(0, y1, 255);*/ + + totalCost = 0; + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; + if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) != 0 || RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) == 0) { + for (y = y0; y <= y1; y += 32) { + for (x = x0; x <= x1; x += 32) { + cost = map_buy_land_rights_for_tile(x, y, setting, flags); + if (cost == MONEY32_UNDEFINED) + return MONEY32_UNDEFINED; + + totalCost += cost; + } + } + } + + return totalCost; +} + +void game_command_buy_land_rights(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp) +{ + + *ebx = map_buy_land_rights( + (*eax & 0xFFFF), + (*ecx & 0xFFFF), + (*edi & 0xFFFF), + (*ebp & 0xFFFF), + (*edx & 0xFF00) >> 8, + *ebx & 0xFF + ); + /*RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_LAND_PURCHASE * 4; + int x = *eax; + int y = *ecx; + int y2 = *ecx; + int z = map_element_height(x + 16, y + 16); + + RCT2_GLOBAL(0x009DEA5E, uint16) = x + 16; + RCT2_GLOBAL(0x009DEA60, uint16) = y + 16; + RCT2_GLOBAL(0x009DEA62, uint16) = z; + + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; + if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) != 0 || RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) == 0) { + + int tile_idx = (((y & 0xFFE0) * 256) + (x & 0xFFE0)) / 32; + while ((TILE_MAP_ELEMENT_POINTER(tile_idx)->type & 0x3C) != 0) { + y += 8; + tile_idx = (((y & 0xFFE0) * 256) + (x & 0xFFE0)) / 32; + } + uint8 ownership = TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership; + uint8 flags = (*edx & 0xFF00) >> 8; + switch (flags) { + case 0: + if ((ownership & OWNERSHIP_OWNED) != 0) { // If the land is already owned + *ebx = 0; + return; + } + else if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) != 0 || (ownership & OWNERSHIP_AVAILABLE) == 0) { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 1726; // Land not for sale! + *ebx = 0x80000000; + return; + } + else { + if ((*ebx & 1) != 0) { + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership |= OWNERSHIP_OWNED; + sub_664D05_(x, y2); + sub_664D05_(x - 32, y2); + sub_664D05_(x + 32, y2); + sub_664D05_(x, y2 + 32); + sub_664D05_(x, y2 - 32); + } + *ebx = RCT2_GLOBAL(RCT2_ADDRESS_LAND_COST, uint16); + return; + } + break; + case 1: + if ((*ebx & 1) != 0) { + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership &= 0xCF; + sub_664D05_(x, y2); + sub_664D05_(x - 32, y2); + sub_664D05_(x + 32, y2); + sub_664D05_(x, y2 + 32); + sub_664D05_(x, y2 - 32); + } + *ebx = 0; + break; + case 2: + if ((ownership & (OWNERSHIP_OWNED | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)) != 0) { // If the land or construction rights are already owned + *ebx = 0; + return; + } + else if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) != 0 || (ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE) == 0) { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 1727; // Construction rights not for sale! + *ebx = 0x80000000; + return; + } + else { + if ((*ebx & 1) != 0) { + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership |= OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED; + uint16 baseHeight = TILE_MAP_ELEMENT_POINTER(tile_idx)->base_height; + baseHeight *= 8; + sub_6EC847(x, y2, baseHeight, baseHeight + 16); + } + *ebx = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCTION_RIGHTS_COST, uint16); + return; + } + break; + case 3: + if ((*ebx & 1) != 0) { + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership &= 0xEF; + uint16 baseHeight = TILE_MAP_ELEMENT_POINTER(tile_idx)->base_height; + baseHeight *= 8; + sub_6EC847(x, y2, baseHeight, baseHeight + 16); + } + *ebx = 0; + break; + break; + case 4: + if ((*ebx & 1) != 0) { + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership |= OWNERSHIP_AVAILABLE; + uint16 baseHeight = TILE_MAP_ELEMENT_POINTER(tile_idx)->base_height; + baseHeight *= 8; + sub_6EC847(x, y2, baseHeight, baseHeight + 16); + } + *ebx = 0; + break; + case 5: + if ((*ebx & 1) != 0) { + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership |= OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE; + uint16 baseHeight = TILE_MAP_ELEMENT_POINTER(tile_idx)->base_height; + baseHeight *= 8; + sub_6EC847(x, y2, baseHeight, baseHeight + 16); + } + *ebx = 0; + break; + default: + if (x <= 32) { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 3215; + *ebx = 0x80000000; + return; + } + else if (y <= 32) { + *ebp = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_UNITS, uint16); + *ebp -= 32; + if (x >= *ebp || y >= *ebp) { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 3215; + *ebx = 0x80000000; + return; + } + else { + int tile_idx2 = (((y & 0xFFE0) * 256) + (x & 0xFFE0)) / 32; + ownership = TILE_MAP_ELEMENT_POINTER(tile_idx2)->properties.surface.ownership; + do { + y += 8; + tile_idx2 = (((y & 0xFFE0) * 256) + (x & 0xFFE0)) / 32; + if ((TILE_MAP_ELEMENT_POINTER(tile_idx2)->type & 0x3C) == 0x10) { + *ebx = 0; + return; + } + + } while ((TILE_MAP_ELEMENT_POINTER(((((y - 8) & 0xFFE0) * 256) + (x & 0xFFE0)) / 32)->flags & 0x80) == 0); + + uint8 bh = (*ebx & 0xFF00) >> 4; + if (bh == (TILE_MAP_ELEMENT_POINTER(tile_idx2)->properties.surface.ownership & 0xF0)) { + *ebx = 0; + return; + } + else { + if ((*ebx & 1) == 0) { + *ebx = RCT2_GLOBAL(RCT2_ADDRESS_LAND_COST, uint16); + return; + } + if ((bh & 0xF0) == 0) { + uint16 bp = RCT2_GLOBAL(RCT2_ADDRESS_PEEP_SPAWNS, uint16); + if (x != (bp & 0xFFE0)) { + bp = RCT2_GLOBAL(RCT2_ADDRESS_PEEP_SPAWNS + 2, uint16); + if (y2 != (bp & 0xFFE0)) { + RCT2_GLOBAL(RCT2_ADDRESS_PEEP_SPAWNS, uint16) = 0xFFFF; + } + } + bp = RCT2_GLOBAL(0x13573F8, uint16); + if (x != (bp & 0xFFE0)) { + bp = RCT2_GLOBAL(0x13573F8 + 2, uint16); + if (y2 != (bp & 0xFFE0)) { + RCT2_GLOBAL(0x13573F8, uint16) = 0xFFFF; + } + } + } + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership &= 0x0F; + TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership |= bh; + sub_664D05_(x, y2); + sub_664D05_(x - 32, y2); + sub_664D05_(x + 32, y2); + sub_664D05_(x, y2 + 32); + sub_664D05_(x, y2 - 32); + RCT2_GLOBAL(0x9E2E28, uint8) |= 1; + + *ebx = 0; + return; + } + } + } + break; + } + } + else { + // Should this ever be called? esi is never set properly + if ((*ebx & 1) != 0) { + //TILE_MAP_ELEMENT_POINTER(tile_idx)->properties.surface.ownership |= OWNERSHIP_OWNED; + sub_664D05_(x, y); + sub_664D05_(x - 32, y2); + sub_664D05_(x + 32, y2); + sub_664D05_(x, y2 + 32); + sub_664D05_(x, y2 - 32); + } + *ebx = RCT2_GLOBAL(RCT2_ADDRESS_LAND_COST, uint16); + }*/ } /** @@ -850,7 +1305,28 @@ static void window_park_entrance_tooldrag() window_tool_get_registers(w, widgetIndex, x, y); - RCT2_CALLPROC_X(0x006681FB, x, y, 0, widgetIndex, (int)w, 0, 0); + //RCT2_CALLPROC_X(0x006681FB, x, y, 0, widgetIndex, (int)w, 0, 0); + + rct_window* w2 = window_find_by_number(0xB, 0); + + if (!w2) { + switch (widgetIndex) { + case WIDX_BUY_LAND_RIGHTS: + screen_pos_to_map_pos(&x, &y, NULL); + if (x != (sint16)0x8000) { + RCT2_GLOBAL(0x00141E9AE, rct_string_id) = 0x6BD; + // I doubt the low byte of dx is required but its not cleared from earlier so copy in the widgetIndex + game_do_command(x, 1, y, 0x00E, 35, 0, 0); + } + break; + case WIDX_BUY_CONSTRUCTION_RIGHTS: + screen_pos_to_map_pos(&x, &y, NULL); + if (x != (sint16)0x8000) { + RCT2_GLOBAL(0x00141E9AE, rct_string_id) = 0x6C0; + game_do_command(x, 1, y, 0x20F, 35, 0, 0); + } + } + } } /** diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c index f78f90820b..1660d9bb75 100644 --- a/src/windows/top_toolbar.c +++ b/src/windows/top_toolbar.c @@ -50,6 +50,7 @@ enum { WIDX_CONSTRUCT_RIDE, WIDX_RIDES, WIDX_PARK, + WIDX_LAND_RIGHTS, WIDX_STAFF, WIDX_GUESTS, WIDX_CLEAR_SCENERY, @@ -104,6 +105,7 @@ static const int left_aligned_widgets_order[] = { static const int right_aligned_widgets_order[] = { WIDX_GUESTS, WIDX_STAFF, + WIDX_LAND_RIGHTS, WIDX_PARK, WIDX_RIDES, WIDX_RESEARCH, @@ -137,6 +139,7 @@ static rct_widget window_top_toolbar_widgets[] = { { WWT_TRNBTN, 2, 0x0183, 0x01A0, 0, 27, 0x20000000 | SPR_TOOLBAR_CONSTRUCT_RIDE, STR_BUILD_RIDE_TIP }, // Construct ride { WWT_TRNBTN, 3, 0x01EA, 0x0207, 0, 27, 0x20000000 | SPR_TOOLBAR_RIDES, STR_RIDES_IN_PARK_TIP }, // Rides { WWT_TRNBTN, 3, 0x0208, 0x0225, 0, 27, 0x20000000 | SPR_TOOLBAR_PARK, STR_PARK_INFORMATION_TIP }, // Park + { WWT_TRNBTN, 3, 0x0208, 0x0225, 0, 27, 0x20000000 | 0x15F9, 5135 }, // Land rights { WWT_TRNBTN, 3, 0x0226, 0x0243, 0, 27, 0x20000000 | 0x15F9, STR_STAFF_TIP }, // Staff { WWT_TRNBTN, 3, 0x0230, 0x024D, 0, 27, 0x20000000 | SPR_TOOLBAR_GUESTS, STR_GUESTS_TIP }, // Guests { WWT_TRNBTN, 2, 0x0230, 0x024D, 0, 27, 0x20000000 | SPR_TOOLBAR_CLEAR_SCENERY, STR_CLEAR_SCENERY_TIP }, // Clear scenery @@ -197,6 +200,7 @@ void toggle_footpath_window(); void toggle_land_window(rct_window *topToolbar, int widgetIndex); void toggle_clear_scenery_window(rct_window *topToolbar, int widgetIndex); void toggle_water_window(rct_window *topToolbar, int widgetIndex); +void toggle_land_rights_window(rct_window *topToolbar, int widgetIndex); /** * Creates the main game top toolbar window. @@ -296,6 +300,9 @@ static void window_top_toolbar_mouseup() case WIDX_PARK: window_park_entrance_open(); break; + case WIDX_LAND_RIGHTS: + toggle_land_rights_window(w, WIDX_LAND_RIGHTS); + break; case WIDX_STAFF: window_staff_list_open(); break; @@ -482,6 +489,7 @@ static void window_top_toolbar_invalidate() window_top_toolbar_widgets[WIDX_CONSTRUCT_RIDE].type = WWT_TRNBTN; window_top_toolbar_widgets[WIDX_RIDES].type = WWT_TRNBTN; window_top_toolbar_widgets[WIDX_PARK].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_LAND_RIGHTS].type = WWT_TRNBTN; window_top_toolbar_widgets[WIDX_STAFF].type = WWT_TRNBTN; window_top_toolbar_widgets[WIDX_GUESTS].type = WWT_TRNBTN; window_top_toolbar_widgets[WIDX_CLEAR_SCENERY].type = WWT_TRNBTN; @@ -492,6 +500,7 @@ static void window_top_toolbar_invalidate() window_top_toolbar_widgets[WIDX_PAUSE].type = WWT_EMPTY; window_top_toolbar_widgets[WIDX_RIDES].type = WWT_EMPTY; window_top_toolbar_widgets[WIDX_PARK].type = WWT_EMPTY; + window_top_toolbar_widgets[WIDX_LAND_RIGHTS].type = WWT_EMPTY; window_top_toolbar_widgets[WIDX_STAFF].type = WWT_EMPTY; window_top_toolbar_widgets[WIDX_GUESTS].type = WWT_EMPTY; window_top_toolbar_widgets[WIDX_FINANCES].type = WWT_EMPTY; @@ -622,6 +631,14 @@ static void window_top_toolbar_paint() gfx_draw_sprite(dpi, imgId, x, y, 0); } + // Draw land rights button + if (window_top_toolbar_widgets[WIDX_LAND_RIGHTS].type != WWT_EMPTY) { + x = w->x + window_top_toolbar_widgets[WIDX_LAND_RIGHTS].left + 3; + y = w->y + window_top_toolbar_widgets[WIDX_LAND_RIGHTS].top + 1; + imgId = SPR_BUY_LAND_RIGHTS; + gfx_draw_sprite(dpi, imgId, x, y, 0); + } + // Draw research button if (window_top_toolbar_widgets[WIDX_RESEARCH].type != WWT_EMPTY) { x = w->x + window_top_toolbar_widgets[WIDX_RESEARCH].left - 1; @@ -1482,6 +1499,30 @@ static void window_top_toolbar_tool_update() case WIDX_SCENERY: RCT2_CALLPROC_X(0x006E287B, x, y, 0, widgetIndex, (int)w, 0, 0); break; + case WIDX_LAND_RIGHTS: + RCT2_CALLPROC_X(0x0068E213, x, y, 0, widgetIndex, (int)w, 0, 0); + RCT2_GLOBAL(0x00F1AD62, uint32) = game_do_command( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), + 0, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), + LandRightsMode ? 0x00E : 0x20F, + 35, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) + ); + //map_invalidate_selection_rect(); + //RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= 0xFFFE; + //screen_pos_to_map_pos(&x, &y, NULL); + /*if (x != SPRITE_LOCATION_NULL) { + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= 1; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 4; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16) = x; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16) = x; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16) = y; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) = y; + map_invalidate_selection_rect(); + }*/ + break; } } @@ -1536,6 +1577,40 @@ static void window_top_toolbar_tool_down(){ case WIDX_SCENERY: window_top_toolbar_scenery_tool_down(x, y, w, widgetIndex); break; + case WIDX_LAND_RIGHTS: + if (LandRightsMode) { + //screen_pos_to_map_pos(&x, &y, NULL); + if (x != (sint16)0x8000) { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, rct_string_id) = 0x6BD; // Can't buy land... + //game_do_command(x, 1, y, 0x00E, 35, 0, 0); + game_do_command( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), + 1, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), + 0x00E, + 35, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) + ); + } + } + else { + //screen_pos_to_map_pos(&x, &y, NULL); + if (x != (sint16)0x8000) { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, rct_string_id) = 0x6C0; // Can't buy construction rights here... + //game_do_command(x, 1, y, 0x20F, 35, 0, 0); + game_do_command( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), + 1, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), + 0x20F, + 35, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) + ); + } + } + break; } } @@ -1783,6 +1858,40 @@ static void window_top_toolbar_tool_drag() if (window_scenery_is_repaint_scenery_tool_on & 1) window_top_toolbar_scenery_tool_down(x, y, w, widgetIndex); break; + case WIDX_LAND_RIGHTS: + if (LandRightsMode) { + //screen_pos_to_map_pos(&x, &y, NULL); + if (x != (sint16)0x8000) { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, rct_string_id) = 0x6BD; // Can't buy land... + //game_do_command(x, 1, y, 0x00E, 35, 0, 0); + game_do_command( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), + 1, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), + 0x00E, + 35, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) + ); + } + } + else { + //screen_pos_to_map_pos(&x, &y, NULL); + if (x != (sint16)0x8000) { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, rct_string_id) = 0x6C0; // Can't buy construction rights here... + //game_do_command(x, 1, y, 0x20F, 35, 0, 0); + game_do_command( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), + 1, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), + 0x20F, + 35, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) + ); + } + } + break; } } @@ -1960,3 +2069,17 @@ void toggle_water_window(rct_window *topToolbar, int widgetIndex) window_water_open(); } } + +void toggle_land_rights_window(rct_window *topToolbar, int widgetIndex) +{ + if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 14) { + tool_cancel(); + } + else { + show_gridlines(); + tool_set(topToolbar, widgetIndex, 19); + RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6; + RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1; + window_land_rights_open(); + } +} \ No newline at end of file diff --git a/src/world/map.c b/src/world/map.c index 2fa984c2a3..f9f585932e 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -48,6 +48,7 @@ const rct_xy16 TileDirectionDelta[] = { rct_xy16 *gMapSelectionTiles = (rct_xy16*)0x009DE596; bool LandPaintMode; +bool LandRightsMode; int _sub_6A876D_save_x; int _sub_6A876D_save_y; diff --git a/src/world/map.h b/src/world/map.h index 6791dae208..246059794a 100644 --- a/src/world/map.h +++ b/src/world/map.h @@ -244,6 +244,8 @@ extern const rct_xy16 TileDirectionDelta[]; extern rct_xy16 *gMapSelectionTiles; // Used in the land tool window to allow dragging and changing land styles extern bool LandPaintMode; +// Used in the land rights tool window to either buy land rights or construction rights +extern bool LandRightsMode; void map_init(int size); void map_update_tile_pointers();