From e857f2d3c84edf5212f37cec485dbcb5f7456e83 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 11 Nov 2015 20:24:59 +0000 Subject: [PATCH] Refactor set_banner and set_large_scenery --- src/world/map.c | 157 +++++++++++++++++++++--------------------------- 1 file changed, 67 insertions(+), 90 deletions(-) diff --git a/src/world/map.c b/src/world/map.c index 72285dfd52..e909630b87 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -1226,8 +1226,9 @@ void game_command_set_large_scenery_colour(int* eax, int* ebx, int* ecx, int* ed int x = *eax; int y = *ecx; uint8 map_element_direction = *ebx >> 8; + uint8 flags = *ebx & 0xFF; uint8 base_height = *edx; - uint8 scenerymultiple_index = *edx >> 8; + uint8 tileIndex = *edx >> 8; uint8 color1 = *ebp; uint8 color2 = *ebp >> 8; int z = map_element_height(x, y); @@ -1235,100 +1236,66 @@ void game_command_set_large_scenery_colour(int* eax, int* ebx, int* ecx, int* ed RCT2_GLOBAL(RCT2_ADDRESS_COMMAND_MAP_Y, uint16) = y + 16; RCT2_GLOBAL(RCT2_ADDRESS_COMMAND_MAP_Z, uint16) = z; + rct_map_element *map_element = map_get_large_scenery_segment(x, y, base_height, map_element_direction, tileIndex); - rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32); - while(map_element_get_type(map_element) != MAP_ELEMENT_TYPE_SCENERY_MULTIPLE || - map_element->base_height != base_height || - map_element->properties.scenerymultiple.type >> 10 != scenerymultiple_index || - (map_element->type & MAP_ELEMENT_DIRECTION_MASK) != map_element_direction){ - map_element++; - if((map_element - 1)->flags & MAP_ELEMENT_FLAG_LAST_TILE){ - *ebx = 0; - return; - } - } - if((*ebx & 0x40) && !(map_element->flags & MAP_ELEMENT_FLAG_GHOST)){ + if(map_element == NULL){ *ebx = 0; return; } - int ecx2 = map_element->properties.scenerymultiple.type >> 10; - rct_scenery_entry* scenery_entry = RCT2_ADDRESS(RCT2_ADDRESS_LARGE_SCENERY_ENTRIES, rct_scenery_entry*)[map_element->properties.scenerymultiple.type & 0x3FF]; - int x2 = scenery_entry->large_scenery.tiles[ecx2].x_offset; - int y2 = scenery_entry->large_scenery.tiles[ecx2].y_offset; - int z2 = (base_height * 8) - scenery_entry->large_scenery.tiles[ecx2].z_offset; - switch(map_element->type & MAP_ELEMENT_DIRECTION_MASK){ - case MAP_ELEMENT_DIRECTION_WEST: - break; - case MAP_ELEMENT_DIRECTION_NORTH:{ - int temp = x2; - x2 = y2; - y2 = -temp; - }break; - case MAP_ELEMENT_DIRECTION_EAST: - x2 = -x2; - y2 = -y2; - break; - case MAP_ELEMENT_DIRECTION_SOUTH:{ - int temp = y2; - y2 = x2; - x2 = -temp; - }break; + + if((flags & GAME_COMMAND_FLAG_GHOST) && !(map_element->flags & MAP_ELEMENT_FLAG_GHOST)){ + *ebx = 0; + return; } - x2 = -x2 + x; - y2 = -y2 + y; - int i = 0; - while(1){ - if(scenery_entry->large_scenery.tiles[i].x_offset == -1){ - *ebx = 0; - return; - } - int x3 = scenery_entry->large_scenery.tiles[i].x_offset; - int y3 = scenery_entry->large_scenery.tiles[i].y_offset; - int z3 = scenery_entry->large_scenery.tiles[i].z_offset; - switch(map_element->type & MAP_ELEMENT_DIRECTION_MASK){ - case MAP_ELEMENT_DIRECTION_WEST: - break; - case MAP_ELEMENT_DIRECTION_NORTH:{ - int temp = x3; - x3 = y3; - y3 = -temp; - }break; - case MAP_ELEMENT_DIRECTION_EAST: - x3 = -x3; - y3 = -y3; - break; - case MAP_ELEMENT_DIRECTION_SOUTH:{ - int temp = y3; - y3 = x3; - x3 = -temp; - }break; - } - x3 += x2; - y3 += y2; - z3 += z2; + + rct_scenery_entry* scenery_entry = RCT2_ADDRESS(RCT2_ADDRESS_LARGE_SCENERY_ENTRIES, rct_scenery_entry*)[map_element->properties.scenerymultiple.type & 0x3FF]; + + // Work out the base tile coordinates (Tile with index 0) + rct_xyz16 baseTile = { + .x = scenery_entry->large_scenery.tiles[tileIndex].x_offset, + .y = scenery_entry->large_scenery.tiles[tileIndex].y_offset, + .z = (base_height * 8) - scenery_entry->large_scenery.tiles[tileIndex].z_offset + }; + rotate_map_coordinates(&baseTile.x, &baseTile.y, map_element_direction); + baseTile.x = x - baseTile.x; + baseTile.y = y - baseTile.y; + + for (int i = 0; scenery_entry->large_scenery.tiles[i].x_offset != -1; ++i) { + assert(i < 256); + + // Work out the current tile coordinates + rct_xyz16 currentTile = { + .x = scenery_entry->large_scenery.tiles[i].x_offset, + .y = scenery_entry->large_scenery.tiles[i].y_offset, + .z = scenery_entry->large_scenery.tiles[i].z_offset + }; + rotate_map_coordinates(¤tTile.x, ¤tTile.y, map_element_direction); + currentTile.x += baseTile.x; + currentTile.y += baseTile.y; + currentTile.z += baseTile.z; + if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode){ - if (!map_is_location_owned(x3, y3, z3)){ + if (!map_is_location_owned(currentTile.x, currentTile.y, currentTile.z)){ *ebx = MONEY32_UNDEFINED; return; } } - if(*ebx & GAME_COMMAND_FLAG_APPLY){ - rct_map_element* map_element = map_get_first_element_at(x3 / 32, y3 / 32); - while(map_element_get_type(map_element) != MAP_ELEMENT_TYPE_SCENERY_MULTIPLE || - (map_element->type & MAP_ELEMENT_DIRECTION_MASK) != map_element_direction || - map_element->properties.scenerymultiple.type >> 10 != i || - map_element->base_height != base_height){ - map_element++; - } - map_element->properties.scenerymultiple.colour[0] &= 0xE0; - map_element->properties.scenerymultiple.colour[0] |= color1; - map_element->properties.scenerymultiple.colour[1] &= 0xE0; - map_element->properties.scenerymultiple.colour[1] |= color2; - map_invalidate_tile_full(x3, y3); - } + if(flags & GAME_COMMAND_FLAG_APPLY){ + rct_map_element* mapElement = map_get_large_scenery_segment( + currentTile.x, + currentTile.y, + base_height, + map_element_direction, + i); - i++; + mapElement->properties.scenerymultiple.colour[0] &= 0xE0; + mapElement->properties.scenerymultiple.colour[0] |= color1; + mapElement->properties.scenerymultiple.colour[1] &= 0xE0; + mapElement->properties.scenerymultiple.colour[1] |= color2; + + map_invalidate_tile_full(currentTile.x, currentTile.y); + } } *ebx = 0; } @@ -1359,14 +1326,24 @@ void game_command_set_banner_colour(int* eax, int* ebx, int* ecx, int* edx, int* if(*ebx & GAME_COMMAND_FLAG_APPLY){ rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32); - while(map_element->type != MAP_ELEMENT_TYPE_BANNER || - map_element->properties.banner.position != banner_position){ - map_element++; - if((map_element - 1)->flags & MAP_ELEMENT_FLAG_LAST_TILE){ - *ebx = MONEY32_UNDEFINED; - return; - } + + bool found = false; + do { + if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_BANNER) + continue; + + if (map_element->properties.banner.position != banner_position) + continue; + + found = true; + break; + } while (!map_element_is_last_for_tile(map_element++)); + + if (found == false){ + *ebx = MONEY32_UNDEFINED; + return; } + rct_window* window = window_find_by_number(WC_BANNER, map_element->properties.banner.index); if(window){ window_invalidate(window);