diff --git a/data/language/english_uk.txt b/data/language/english_uk.txt index f8d1c578f1..ac35126d2a 100644 --- a/data/language/english_uk.txt +++ b/data/language/english_uk.txt @@ -3466,3 +3466,7 @@ STR_5129 :Enter selection size between {COMMA16} and {COMMA16} STR_5130 :Map size STR_5131 :Enter map size between {COMMA16} and {COMMA16} STR_5132 :Fix all rides +STR_5133 :{SMALLFONT}{BLACK}Adjust smaller area of land rights +STR_5134 :{SMALLFONT}{BLACK}Adjust larger area of land rights +STR_5135 :{SMALLFONT}{BLACK}Buy land rights and construction rights +STR_5136 :Land rights 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 a5f141b3e5..8e8d1d800e 100644 --- a/src/game.c +++ b/src/game.c @@ -910,7 +910,7 @@ static uint32 game_do_command_table[58] = { 0, 0, 0, - 0x006649BD, + 0,//0x006649BD, //buy_land_rights 0x006666E7, 0, 0x006CD8CE, @@ -973,7 +973,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/game.h b/src/game.h index 4f736ede2b..102bd7d1c5 100644 --- a/src/game.h +++ b/src/game.h @@ -59,7 +59,7 @@ enum GAME_COMMAND { GAME_COMMAND_SET_STAFF_ORDER, // 32 GAME_COMMAND_SET_PARK_NAME, GAME_COMMAND_SET_PARK_OPEN, // 34 - GAME_COMMAND_35, + GAME_COMMAND_BUY_LAND_RIGHTS, // 35 GAME_COMMAND_PLACE_PARK_ENTRANCE, GAME_COMMAND_REMOVE_PARK_ENTRANCE, GAME_COMMAND_38, 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/windows/land_rights.c b/src/windows/land_rights.c new file mode 100644 index 0000000000..5cc8961628 --- /dev/null +++ b/src/windows/land_rights.c @@ -0,0 +1,283 @@ +/***************************************************************************** + * 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" +#include "../game.h" + +const int MAX_LAND_RIGHTS_SIZE = 64; + +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, 5136, 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, SPR_BUY_LAND_RIGHTS_TIP }, // land rights + { WWT_FLATBTN, 2, 52, 75, 53, 76, 0x20000000 | SPR_BUY_CONSTRUCTION_RIGHTS, SPR_BUY_CONSTRUCTION_RIGHTS_TIP }, // 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(); +} + +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); + } + break; + case WIDX_BUY_CONSTRUCTION_RIGHTS: + if (LandRightsMode) { + LandRightsMode = false; + hide_land_rights(); + show_construction_rights(); + window_invalidate(w); + } + 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, 5129, 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_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); +} + +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_PARK_INFORMATION) + 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..e77fe386ea 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 { @@ -65,7 +66,7 @@ enum WINDOW_PARK_WIDGET_IDX { WIDX_STATUS, WIDX_OPEN_OR_CLOSE, WIDX_BUY_LAND_RIGHTS, - WIDX_BUY_CONSTRUCTION_RIGHTS, + //WIDX_BUY_CONSTRUCTION_RIGHTS, WIDX_LOCATE, WIDX_RENAME, @@ -95,10 +96,10 @@ static rct_widget window_park_entrance_widgets[] = { { WWT_VIEWPORT, 1, 3, 204, 46, 160, 0x0FFFFFFFF, STR_NONE }, // viewport { WWT_12, 1, 3, 204, 161, 171, 0x0FFFFFFFF, STR_NONE }, // status { WWT_FLATBTN, 1, 205, 228, 49, 72, 0x0FFFFFFFF, STR_OPEN_OR_CLOSE_PARK_TIP }, // open / close - { WWT_FLATBTN, 1, 205, 228, 73, 96, SPR_BUY_LAND_RIGHTS, SPR_BUY_LAND_RIGHTS_TIP }, // buy land rights - { WWT_FLATBTN, 1, 205, 228, 97, 120, SPR_BUY_CONSTRUCTION_RIGHTS, SPR_BUY_CONSTRUCTION_RIGHTS_TIP }, // buy construction rights - { WWT_FLATBTN, 1, 205, 228, 121, 144, SPR_LOCATE, STR_LOCATE_SUBJECT_TIP }, // locate - { WWT_FLATBTN, 1, 205, 228, 145, 168, SPR_RENAME, STR_NAME_PARK_TIP }, // rename + { WWT_FLATBTN, 1, 205, 228, 73, 96, SPR_BUY_LAND_RIGHTS, 5135 }, // buy land rights + //{ WWT_FLATBTN, 1, 205, 228, 97, 120, SPR_BUY_CONSTRUCTION_RIGHTS, SPR_BUY_CONSTRUCTION_RIGHTS_TIP }, // buy construction rights + { WWT_FLATBTN, 1, 205, 228, 97, 120, SPR_LOCATE, STR_LOCATE_SUBJECT_TIP }, // locate + { WWT_FLATBTN, 1, 205, 228, 121, 144, SPR_RENAME, STR_NAME_PARK_TIP }, // rename { WIDGETS_END }, }; @@ -229,6 +230,7 @@ static void window_park_entrance_toolabort(); static void window_park_entrance_textinput(); static void window_park_entrance_invalidate(); static void window_park_entrance_paint(); +void toggle_land_rights_window(rct_window *parkWindow, int widgetIndex); static void window_park_rating_mouseup(); static void window_park_rating_resize(); @@ -510,7 +512,7 @@ static uint32 window_park_page_enabled_widgets[] = { (1 << WIDX_TAB_7) | (1 << WIDX_OPEN_OR_CLOSE) | (1 << WIDX_BUY_LAND_RIGHTS) | - (1 << WIDX_BUY_CONSTRUCTION_RIGHTS) | + //(1 << WIDX_BUY_CONSTRUCTION_RIGHTS) | (1 << WIDX_LOCATE) | (1 << WIDX_RENAME), @@ -703,11 +705,12 @@ 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); - break; - case WIDX_BUY_CONSTRUCTION_RIGHTS: - RCT2_CALLPROC_X(0x00668393, 0, 0, 0, widgetIndex, (int)w, 0, 0); + toggle_land_rights_window(w, WIDX_BUY_LAND_RIGHTS); + //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); + // break; case WIDX_LOCATE: window_scroll_to_viewport(w); break; @@ -809,19 +812,19 @@ static void window_park_entrance_toolupdate() window_tool_get_registers(w, widgetIndex, x, y); - if (widgetIndex == WIDX_BUY_LAND_RIGHTS || widgetIndex == WIDX_BUY_CONSTRUCTION_RIGHTS) { - 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(); - } + switch (widgetIndex){ + case WIDX_BUY_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), + 0x4, + 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) + ); + break; } } @@ -836,7 +839,38 @@ 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); + switch (widgetIndex){ + case WIDX_BUY_LAND_RIGHTS: + if (LandRightsMode) { + if (x != (sint16)0x8000) { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, rct_string_id) = 0x6BD; // Can't buy land... + game_do_command( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), + 1, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), + 0x00E, + GAME_COMMAND_BUY_LAND_RIGHTS, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) + ); + } + } + else { + 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( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), + 1, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), + 0x20F, + GAME_COMMAND_BUY_LAND_RIGHTS, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) + ); + } + } + break; + } } /** @@ -850,7 +884,42 @@ 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); + rct_window* w2 = window_find_by_number(0xB, 0); + + if (!w2) { + switch (widgetIndex){ + case WIDX_BUY_LAND_RIGHTS: + if (LandRightsMode) { + if (x != (sint16)0x8000) { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, rct_string_id) = 0x6BD; // Can't buy land... + game_do_command( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), + 1, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), + 0x00E, + GAME_COMMAND_BUY_LAND_RIGHTS, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) + ); + } + } + else { + 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( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), + 1, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), + 0x20F, + GAME_COMMAND_BUY_LAND_RIGHTS, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) + ); + } + } + break; + } + } } /** @@ -866,11 +935,15 @@ static void window_park_entrance_toolabort() if (widgetIndex == WIDX_BUY_LAND_RIGHTS) { hide_gridlines(); - hide_land_rights(); - } else if (widgetIndex == WIDX_BUY_CONSTRUCTION_RIGHTS) { - hide_gridlines(); - hide_construction_rights(); - } + if (LandRightsMode) + hide_land_rights(); + else + hide_construction_rights(); + } + //else if (widgetIndex == WIDX_BUY_CONSTRUCTION_RIGHTS) { + // hide_gridlines(); + // hide_construction_rights(); + //} } /** @@ -933,11 +1006,11 @@ static void window_park_entrance_invalidate() if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY) { window_park_entrance_widgets[WIDX_OPEN_OR_CLOSE].type = WWT_EMPTY; window_park_entrance_widgets[WIDX_BUY_LAND_RIGHTS].type = WWT_EMPTY; - window_park_entrance_widgets[WIDX_BUY_CONSTRUCTION_RIGHTS].type = WWT_EMPTY; + //window_park_entrance_widgets[WIDX_BUY_CONSTRUCTION_RIGHTS].type = WWT_EMPTY; } else { window_park_entrance_widgets[WIDX_OPEN_OR_CLOSE].type = WWT_FLATBTN; window_park_entrance_widgets[WIDX_BUY_LAND_RIGHTS].type = WWT_FLATBTN; - window_park_entrance_widgets[WIDX_BUY_CONSTRUCTION_RIGHTS].type = WWT_FLATBTN; + //window_park_entrance_widgets[WIDX_BUY_CONSTRUCTION_RIGHTS].type = WWT_FLATBTN; } } @@ -1053,6 +1126,20 @@ static void window_park_init_viewport(rct_window *w) window_invalidate(w); } +void toggle_land_rights_window(rct_window *parkWindow, 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(parkWindow, widgetIndex, 2); + RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6; + RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1; + window_land_rights_open(); + } +} + #pragma endregion #pragma region Rating page diff --git a/src/world/map.c b/src/world/map.c index 5c45910260..67c6aaacb4 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 98257aef27..5d2f9985a1 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(); diff --git a/src/world/park.c b/src/world/park.c index ed3cada4ff..78a68a80fc 100644 --- a/src/world/park.c +++ b/src/world/park.c @@ -806,3 +806,413 @@ void game_command_set_park_name(int *eax, int *ebx, int *ecx, int *edx, int *esi *ebx = 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; + + if (x1 == 0 && y1 == 0) { + x1 = x0; + y1 = y0; + } + + 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; + + // Game command modified to accept selection size + 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; +} + +/** +* +* rct2: 0x006649BD +*/ +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 + ); + // Original decompiled function for Duncan to look at: + + /*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); + }*/ +} diff --git a/src/world/park.h b/src/world/park.h index 0a59d21d02..562465cc26 100644 --- a/src/world/park.h +++ b/src/world/park.h @@ -69,6 +69,7 @@ void game_command_set_park_entrance_fee(int *eax, int *ebx, int *ecx, int *edx, void game_command_set_park_open(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); void game_command_remove_park_entrance(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); void game_command_set_park_name(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); +void game_command_buy_land_rights(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); void sub_6EC847(int x, int y, int z0, int z1);