diff --git a/src/game.c b/src/game.c index 3addf119bf..35012ccf73 100644 --- a/src/game.c +++ b/src/game.c @@ -877,7 +877,7 @@ static uint32 game_do_command_table[58] = { 0x006A61DE, 0x006A68AE, 0x006A67C0, - 0x00663CCD, // 20 + 0, // use new_game_command_table, original: 0x00663CCD, // 20 0x006B53E9, 0x00698D6C, // text input 0x0068C542, @@ -940,7 +940,7 @@ static GAME_COMMAND_POINTER* new_game_command_table[58] = { game_command_emptysub, game_command_emptysub, game_command_emptysub, - game_command_emptysub, // 20 + game_command_change_surface_style, // 20 game_command_emptysub, game_command_emptysub, game_command_emptysub, diff --git a/src/game.h b/src/game.h index 64a6f02c7d..13520baf58 100644 --- a/src/game.h +++ b/src/game.h @@ -42,7 +42,7 @@ enum GAME_COMMAND { GAME_COMMAND_PLACE_PATH, // 17 GAME_COMMAND_18, GAME_COMMAND_REMOVE_PATH, // 19 - GAME_COMMAND_20, + GAME_COMMAND_CHANGE_SURFACE_STYLE, //20 GAME_COMMAND_21, GAME_COMMAND_22, //To do with text input GAME_COMMAND_23, @@ -72,7 +72,7 @@ enum GAME_COMMAND { GAME_COMMAND_47, GAME_COMMAND_START_MARKETING_CAMPAIGN, // 48 GAME_COMMAND_49, - GAME_COMMAND_50, + GAME_COMMAND_50, // New banner? (possibly scenery) GAME_COMMAND_51, GAME_COMMAND_52, GAME_COMMAND_53, diff --git a/src/interface/window.c b/src/interface/window.c index c7b573f09c..5a2218b827 100644 --- a/src/interface/window.c +++ b/src/interface/window.c @@ -1660,7 +1660,7 @@ void window_bubble_list_item(rct_window* w, int item_position){ */ void window_resize_gui(int width, int height) { - if (RCT2_GLOBAL(0x9DEA68, uint8) & 0xE){ + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0xE){ window_resize_gui_scenario_editor(width, height); return; } diff --git a/src/windows/game_top_toolbar.c b/src/windows/game_top_toolbar.c index 710fbaf186..16863fd0b3 100644 --- a/src/windows/game_top_toolbar.c +++ b/src/windows/game_top_toolbar.c @@ -477,6 +477,13 @@ static void window_game_top_toolbar_invalidate() { w->disabled_widgets &= ~((1 << WIDX_ZOOM_IN) | (1 << WIDX_ZOOM_OUT)); } + + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY) { + window_game_top_toolbar_widgets[WIDX_FINANCES].type = WWT_EMPTY; + } + else{ + window_game_top_toolbar_widgets[WIDX_FINANCES].type = WWT_TRNBTN; + } } /** @@ -509,10 +516,12 @@ static void window_game_top_toolbar_paint() gfx_draw_sprite(dpi, imgId, x, y, 0); // Draw finances button - x = w->x + window_game_top_toolbar_widgets[WIDX_FINANCES].left + 3; - y = w->y + window_game_top_toolbar_widgets[WIDX_FINANCES].top + 1; - imgId = SPR_FINANCE; - gfx_draw_sprite(dpi, imgId, x, y, 0); + if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY)){ + x = w->x + window_game_top_toolbar_widgets[WIDX_FINANCES].left + 3; + y = w->y + window_game_top_toolbar_widgets[WIDX_FINANCES].top + 1; + imgId = SPR_FINANCE; + gfx_draw_sprite(dpi, imgId, x, y, 0); + } } /** @@ -639,10 +648,24 @@ static void window_game_top_toolbar_tool_down(){ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 12; break; case WIDX_LAND: - RCT2_CALLPROC_X(0x66CBF3, x, y, 0, widgetIndex, (int)w, 0, 0); + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16)&(1 << 0)){ + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, rct_string_id) = 1387; + game_do_command( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), + 1, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_SURFACE, uint8) | (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) << 8), + GAME_COMMAND_CHANGE_SURFACE_STYLE, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) + ); + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 3; + } break; case WIDX_WATER: - RCT2_CALLPROC_X(0x66CC48, x, y, 0, widgetIndex, (int)w, 0, 0); + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16)&(1 << 0)){ + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 3; + } break; case WIDX_SCENERY: window_game_top_toolbar_scenery_tool_down(x, y, w, widgetIndex); diff --git a/src/world/map.c b/src/world/map.c index 6ec218f93f..e0204943df 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -707,6 +707,137 @@ void game_command_clear_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi ); } +/* rct2: 0x00663CCD */ +money32 map_change_surface_style(int x0, int y0, int x1, int y1, uint8 surface_style, uint8 edge_style, uint8 flags) +{ + RCT2_GLOBAL(0x141F56C, uint8) = 12; + + int x_mid, y_mid; + + x_mid = (x0 + x1) / 2 + 16; + y_mid = (y0 + y1) / 2 + 16; + + int height_mid = map_element_height(x_mid, y_mid); + + RCT2_GLOBAL(0x9DEA5E, uint16) = x_mid; + RCT2_GLOBAL(0x9DEA60, uint16) = y_mid; + RCT2_GLOBAL(0x9DEA62, uint16) = height_mid; + RCT2_GLOBAL(0x9E32B4, uint32) = 0; + + money32 cur_cost = 0; + + if (RCT2_GLOBAL(0x9DEA6E, uint8) != 0){ + cur_cost += RCT2_GLOBAL(0x9E32B4, uint32); + + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY){ + return 0; + } + return cur_cost; + } + + if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) && RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES){ + cur_cost += RCT2_GLOBAL(0x9E32B4, uint32); + + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY){ + return 0; + } + return cur_cost; + } + + for (int x = x0; x <= x1; x += 32){ + for (int y = y0; y <= y1; y += 32){ + if (x > 0x1FFF)continue; + if (y > 0x1FFF)continue; + + if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR)){ + if (!map_is_location_in_park(x, y))continue; + } + + rct_map_element* map_element = map_get_surface_element_at(x / 32, y / 32); + + if (surface_style != 0xFF){ + uint8 cur_terrain = ( + (map_element->type&MAP_ELEMENT_DIRECTION_MASK) << 3) + | (map_element->properties.surface.terrain >> 5); + + if (surface_style != cur_terrain){ + RCT2_GLOBAL(0x9E32B4, uint32) += RCT2_ADDRESS(0x97B8B8, uint32)[surface_style & 0x1F]; + + if (flags & 1){ + map_element->properties.surface.terrain &= MAP_ELEMENT_WATER_HEIGHT_MASK; + map_element->type &= MAP_ELEMENT_QUADRANT_MASK | MAP_ELEMENT_TYPE_MASK; + + //Save the new terrain + map_element->properties.surface.terrain |= surface_style << 5; + //Save the new direction mask + map_element->type |= (surface_style >> 3) & MAP_ELEMENT_DIRECTION_MASK; + + map_invalidate_tile_full(x, y); + RCT2_CALLPROC_X(0x673883, x, 0, y, map_element_height(x, y), 0, 0, 0); + } + } + } + + if (edge_style != 0xFF){ + uint8 cur_edge = + ((map_element->type & 0x80) >> 4) + | (map_element->properties.surface.slope >> 5); + + if (edge_style != cur_edge){ + cur_cost++; + + if (flags & 1){ + map_element->properties.surface.slope &= MAP_ELEMENT_SLOPE_MASK; + map_element->type &= 0x7F; + + //Save edge style + map_element->properties.surface.slope |= edge_style << 5; + //Save ??? + map_element->type |= (edge_style << 4) & 0x80; + map_invalidate_tile_full(x, y); + } + } + } + + if (flags & 1){ + if (!(map_element->properties.surface.terrain & MAP_ELEMENT_SURFACE_TERRAIN_MASK)){ + if (!(map_element->type & MAP_ELEMENT_DIRECTION_MASK)){ + if ((map_element->properties.surface.grass_length & 7) != GRASS_LENGTH_CLEAR_0){ + map_element->properties.surface.grass_length = GRASS_LENGTH_CLEAR_0; + map_invalidate_tile_full(x, y); + } + } + } + } + } + } + + cur_cost *= 100; + + cur_cost += RCT2_GLOBAL(0x9E32B4, uint32); + + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY){ + return 0; + } + return cur_cost; +} + +/* rct2: 0x00663CCD */ +void game_command_change_surface_style(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp){ + //RCT2_CALLFUNC_X(0x663CCD, eax, ebx, ecx, edx, esi, edi, ebp); + //return; + + *ebx = map_change_surface_style( + (*eax & 0xFFFF), + (*ecx & 0xFFFF), + (*edi & 0xFFFF), + (*ebp & 0xFFFF), + *edx & 0xFF, + (*edx & 0xFF00) >> 8, + *ebx & 0xFF + ); +} + /** * * rct2: 0x006EC6D7 diff --git a/src/world/map.h b/src/world/map.h index 044c8acd75..971681a06c 100644 --- a/src/world/map.h +++ b/src/world/map.h @@ -24,10 +24,10 @@ #include "../common.h" typedef struct { - uint8 slope; //4 - uint8 terrain; //5 - uint8 grass_length; - uint8 ownership; + uint8 slope; //4 0xE0 Edge Style, 0x1F Slope + uint8 terrain; //5 0xE0 Terrain Style, 0x1F Water height + uint8 grass_length; //6 + uint8 ownership; //7 } rct_map_element_surface_properties; typedef struct { @@ -192,6 +192,7 @@ enum { #define MAP_ELEMENT_DIRECTION_MASK 0x03 #define MAP_ELEMENT_SLOPE_MASK 0x1F +#define MAP_ELEMENT_SLOPE_EDGE_STYLE_MASK 0xE0 #define MAP_ELEMENT_WATER_HEIGHT_MASK 0x1F #define MAP_ELEMENT_SURFACE_TERRAIN_MASK 0xE0 @@ -245,6 +246,7 @@ void map_invalidate_selection_rect(); void fountain_update_all(); void game_command_clear_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp); +void game_command_change_surface_style(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp); #define GET_MAP_ELEMENT(x) (&(RCT2_ADDRESS(RCT2_ADDRESS_MAP_ELEMENTS, rct_map_element)[x])) #define TILE_MAP_ELEMENT_POINTER(x) (RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[x])