From af4653766750d3fefffa7d279604ba35ca9be630 Mon Sep 17 00:00:00 2001 From: zsilencer Date: Tue, 14 Apr 2015 15:17:19 -0600 Subject: [PATCH] game_command_raise_land, game_command_lower_land --- src/game.c | 8 +-- src/world/map.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++ src/world/map.h | 2 + 3 files changed, 165 insertions(+), 4 deletions(-) diff --git a/src/game.c b/src/game.c index c78eae6ba9..d8c47006ce 100644 --- a/src/game.c +++ b/src/game.c @@ -897,8 +897,8 @@ static uint32 game_do_command_table[58] = { 0, // use new_game_command_table, original: 0x00663CCD, // 20 0x006B53E9, 0x00698D6C, // text input - 0x0068C542, - 0x0068C6D1, + 0, + 0, 0x0068BC01, 0x006E66A0, 0x006E6878, @@ -960,8 +960,8 @@ static GAME_COMMAND_POINTER* new_game_command_table[58] = { game_command_change_surface_style, // 20 game_command_emptysub, game_command_emptysub, - game_command_emptysub, - game_command_emptysub, + game_command_raise_land, + game_command_lower_land, game_command_emptysub, game_command_emptysub, game_command_emptysub, diff --git a/src/world/map.c b/src/world/map.c index 480c03ee52..8feb837318 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -19,6 +19,7 @@ *****************************************************************************/ #include "../addresses.h" +#include "../audio/audio.h" #include "../game.h" #include "../interface/window.h" #include "../localisation/date.h" @@ -890,6 +891,164 @@ void game_command_change_surface_style(int* eax, int* ebx, int* ecx, int* edx, i ); } +/** + * + * rct2: 0x0068C542 + */ +void game_command_raise_land(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) +{ + int x = *eax; + int y = *ecx; + int z = map_element_height(*eax, *ecx); + int ax = (uint16)*edx; + int ay = (uint16)*ebp; + int bx = (uint16)(*edx >> 16); + int by = (uint16)(*ebp >> 16); + uint16 selection_type = *edi; + + int cost = 0x80000000; + + if(*ebx & GAME_COMMAND_FLAG_APPLY && RCT2_GLOBAL(0x009A8C28, uint8) == 1){ + sound_play_panned(SOUND_PLACE_ITEM, 0x8001, x, y, z); + } + + uint8 dh = 0xFF; + + // find lowest map element in selection + for(int yi = ay; yi <= by; yi += 32){ + for(int xi = ax; xi <= bx; xi += 32){ + int tile_idx = (((yi & 0x1FE0) * 256) + (xi & 0x1FE0)) / 32; + rct_map_element* map_element = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; + while(map_element->type & MAP_ELEMENT_TYPE_MASK){ + map_element++; + } + if(dh > map_element->base_height){ + dh = map_element->base_height; + } + } + } + + for(int yi = ay; yi <= by; yi += 32){ + for(int xi = ax; xi <= bx; xi += 32){ + int tile_idx = (((yi & 0x1FE0) * 256) + (xi & 0x1FE0)) / 32; + rct_map_element* map_element = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; + while(map_element->type & MAP_ELEMENT_TYPE_MASK){ + map_element++; + } + uint8 dl = map_element->base_height; + if(dl <= dh){ + uint8 dh = RCT2_ADDRESS(0x00981A1E, uint8)[(selection_type * 32) + (map_element->properties.surface.slope & MAP_ELEMENT_SLOPE_MASK)]; // lookup table + if(dh & 0x20){ // needs to be raised, otherwise just the slope type changes + dl += 2; + dh &= ~0x20; + } + int ebx2 = *ebx; + int edx2 = (dh << 8) + dl; + int edi2 = selection_type * 32; + RCT2_CALLFUNC_X(0x0066397F, &xi, &ebx2, &yi, &edx2, (int*)&map_element, &edi2, ebp); // actually apply the change + if(ebx2 != 0x80000000){ + if(cost == 0x80000000){ + cost = ebx2; + }else{ + cost += ebx2; + } + } + } + } + } + RCT2_GLOBAL(0x141F56C, uint8) = 12; + RCT2_GLOBAL(0x009DEA5E, uint32) = x; + RCT2_GLOBAL(0x009DEA60, uint32) = y; + RCT2_GLOBAL(0x009DEA62, uint32) = z; + *ebx = cost; +} + +/** + * + * rct2: 0x0068C6D1 + */ +void game_command_lower_land(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) +{ + int x = *eax; + int y = *ecx; + int z = map_element_height(*eax, *ecx); + int ax = (uint16)*edx; + int ay = (uint16)*ebp; + int bx = (uint16)(*edx >> 16); + int by = (uint16)(*ebp >> 16); + uint16 selection_type = *edi; + + int cost = 0x80000000; + + if(*ebx & GAME_COMMAND_FLAG_APPLY && RCT2_GLOBAL(0x009A8C28, uint8) == 1){ + sound_play_panned(SOUND_PLACE_ITEM, 0x8001, x, y, z); + } + + uint8 dh = 0; + + // find highest map element in selection + for(int yi = ay; yi <= by; yi += 32){ + for(int xi = ax; xi <= bx; xi += 32){ + int tile_idx = (((yi & 0x1FE0) * 256) + (xi & 0x1FE0)) / 32; + rct_map_element* map_element = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; + while(map_element->type & MAP_ELEMENT_TYPE_MASK){ + map_element++; + } + uint8 dl = map_element->base_height; + if(map_element->properties.surface.slope & 0xF){ + dl += 2; + } + if(map_element->properties.surface.slope & 0x10){ + dl += 2; + } + if(dh < dl){ + dh = dl; + } + } + } + + for(int yi = ay; yi <= by; yi += 32){ + for(int xi = ax; xi <= bx; xi += 32){ + int tile_idx = (((yi & 0x1FE0) * 256) + (xi & 0x1FE0)) / 32; + rct_map_element* map_element = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; + while(map_element->type & MAP_ELEMENT_TYPE_MASK){ + map_element++; + } + uint8 dl = map_element->base_height; + if(map_element->properties.surface.slope & 0xF){ + dl += 2; + } + if(map_element->properties.surface.slope & 0x10){ + dl += 2; + } + if(dl >= dh){ + dl = map_element->base_height; + uint8 dh = RCT2_ADDRESS(0x00981ABE, uint8)[(selection_type * 32) + (map_element->properties.surface.slope & MAP_ELEMENT_SLOPE_MASK)]; // lookup table + if(dh & 0x20){ // needs to be lowered, otherwise just the slope type changes + dl -= 2; + dh &= ~0x20; + } + int ebx2 = *ebx; + int edx2 = (dh << 8) + dl; + int edi2 = selection_type * 32; + RCT2_CALLFUNC_X(0x0066397F, &xi, &ebx2, &yi, &edx2, (int*)&map_element, &edi2, ebp); // actually apply the change + if(ebx2 != 0x80000000){ + if(cost == 0x80000000){ + cost = ebx2; + }else{ + cost += ebx2; + } + } + } + } + } + RCT2_GLOBAL(0x141F56C, uint8) = 12; + RCT2_GLOBAL(0x009DEA5E, uint32) = x; + RCT2_GLOBAL(0x009DEA60, uint32) = y; + RCT2_GLOBAL(0x009DEA62, uint32) = z; + *ebx = cost; +} + /** * * rct2: 0x006EC6D7 diff --git a/src/world/map.h b/src/world/map.h index e8824796a9..762a33f232 100644 --- a/src/world/map.h +++ b/src/world/map.h @@ -275,6 +275,8 @@ int map_can_construct_at(int x, int y, int zLow, int zHigh, uint8 bl); 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); +void game_command_raise_land(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp); +void game_command_lower_land(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])