From 9087170cf1118cf480aefe26aa5395c46503dbf0 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Thu, 9 Mar 2017 20:30:19 +0000 Subject: [PATCH 1/5] Move functions into banner.cpp --- src/openrct2/libopenrct2.vcxproj | 4 +- src/openrct2/world/banner.c | 169 ---------- src/openrct2/world/banner.cpp | 558 +++++++++++++++++++++++++++++++ src/openrct2/world/banner.h | 2 +- src/openrct2/world/map.c | 370 -------------------- src/openrct2/world/wall.cpp | 2 +- 6 files changed, 562 insertions(+), 543 deletions(-) delete mode 100644 src/openrct2/world/banner.c create mode 100644 src/openrct2/world/banner.cpp diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 40212868c5..448829cc8d 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -336,6 +336,7 @@ + @@ -405,7 +406,6 @@ - @@ -618,4 +618,4 @@ - \ No newline at end of file + diff --git a/src/openrct2/world/banner.c b/src/openrct2/world/banner.c deleted file mode 100644 index 43b664bd20..0000000000 --- a/src/openrct2/world/banner.c +++ /dev/null @@ -1,169 +0,0 @@ -#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers -/***************************************************************************** - * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. - * - * OpenRCT2 is the work of many authors, a full list can be found in contributors.md - * For more information, visit https://github.com/OpenRCT2/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. - * - * A full copy of the GNU General Public License can be found in licence.txt - *****************************************************************************/ -#pragma endregion - -#include "../game.h" -#include "../localisation/localisation.h" -#include "../ride/ride.h" -#include "banner.h" -#include "map.h" - -rct_banner gBanners[MAX_BANNERS]; - -/** - * - * rct2: 0x006B9CB0 - */ -void banner_init() -{ - for (sint32 i = 0; i < MAX_BANNERS; i++) { - gBanners[i].type = BANNER_NULL; - } -} - -/** - * Creates a new banner and returns the index of the banner - * If the flag GAME_COMMAND_FLAG_APPLY is NOT set then returns - * the first unused index but does NOT mark the banner as created. - * returns 0xFF on failure. - * - * rct2: 0x006BA278 - */ -sint32 create_new_banner(uint8 flags) -{ - sint32 banner_index = 0; - for (; banner_index < MAX_BANNERS; banner_index++){ - if (gBanners[banner_index].type == BANNER_NULL){ - break; - } - } - - if (banner_index == MAX_BANNERS){ - gGameCommandErrorText = STR_TOO_MANY_BANNERS_IN_GAME; - return BANNER_NULL; - } - - if (flags & GAME_COMMAND_FLAG_APPLY){ - rct_banner* banner = &gBanners[banner_index]; - - banner->flags = 0; - banner->type = 0; - banner->string_idx = STR_DEFAULT_SIGN; - banner->colour = 2; - banner->text_colour = 2; - } - return banner_index; -} - -rct_map_element *banner_get_map_element(sint32 bannerIndex) -{ - rct_banner *banner = &gBanners[bannerIndex]; - rct_map_element *mapElement = map_get_first_element_at(banner->x, banner->y); - do { - if (map_element_get_banner_index(mapElement) == bannerIndex) { - return mapElement; - } - } while (!map_element_is_last_for_tile(mapElement++)); - return NULL; -} - -/** - * - * rct2: 0x006B7EAB - */ -static sint32 banner_get_ride_index_at(sint32 x, sint32 y, sint32 z) -{ - rct_map_element *mapElement; - rct_ride *ride; - sint32 rideIndex, resultRideIndex; - - resultRideIndex = -1; - mapElement = map_get_first_element_at(x >> 5, y >> 5); - do { - if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_TRACK) - continue; - - rideIndex = mapElement->properties.track.ride_index; - ride = get_ride(rideIndex); - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) - continue; - - if ((mapElement->clearance_height * 8) + 32 <= z) - continue; - - resultRideIndex = rideIndex; - } while (!map_element_is_last_for_tile(mapElement++)); - - return resultRideIndex; -} - -/** - * - * rct2: 0x006B7D86 - */ -sint32 banner_get_closest_ride_index(sint32 x, sint32 y, sint32 z) -{ - sint32 i, rideIndex; - rct_ride *ride; - - static const rct_xy16 NeighbourCheckOrder[] = { - { 32, 0 }, - { -32, 0 }, - { 0, 32 }, - { 0, -32 }, - { -32, +32 }, - { +32, -32 }, - { +32, +32 }, - { -32, +32 }, - { 0, 0 } - }; - - for (i = 0; i < countof(NeighbourCheckOrder); i++) { - rideIndex = banner_get_ride_index_at(x + NeighbourCheckOrder[i].x, y + NeighbourCheckOrder[i].y, z); - if (rideIndex != -1) { - return rideIndex; - } - } - - rideIndex = -1; - sint32 resultDistance = INT_MAX; - FOR_ALL_RIDES(i, ride) { - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) - continue; - - uint16 xy = ride->overall_view; - if (xy == 0xFFFF) - continue; - - sint32 rideX = (xy & 0xFF) * 32; - sint32 rideY = (xy >> 8) * 32; - sint32 distance = abs(x - rideX) + abs(y - rideY); - if (distance < resultDistance) { - resultDistance = distance; - rideIndex = i; - } - } - - return rideIndex; -} - -void fix_banner_count() -{ - for (sint32 banner_index = 0; banner_index < MAX_BANNERS; banner_index++){ - rct_map_element *map_element = banner_get_map_element(banner_index); - if(map_element==NULL) - gBanners[banner_index].type = BANNER_NULL; - } -} diff --git a/src/openrct2/world/banner.cpp b/src/openrct2/world/banner.cpp new file mode 100644 index 0000000000..c2d41f732e --- /dev/null +++ b/src/openrct2/world/banner.cpp @@ -0,0 +1,558 @@ +#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers +/***************************************************************************** + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * OpenRCT2 is the work of many authors, a full list can be found in contributors.md + * For more information, visit https://github.com/OpenRCT2/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. + * + * A full copy of the GNU General Public License can be found in licence.txt + *****************************************************************************/ +#pragma endregion + +#include "../core/util.hpp" +#include "../network/network.h" + +extern "C" +{ + #include "../game.h" + #include "../localisation/localisation.h" + #include "../ride/ride.h" + #include "../interface/window.h" + #include "../util/util.h" + #include "scenery.h" + #include "banner.h" + #include "map.h" + #include "park.h" +} + +rct_banner gBanners[MAX_BANNERS]; + +extern "C" +{ + /** + * + * rct2: 0x006B9CB0 + */ + void banner_init() + { + for (sint32 i = 0; i < MAX_BANNERS; i++) { + gBanners[i].type = BANNER_NULL; + } + } + + /** + * Creates a new banner and returns the index of the banner + * If the flag GAME_COMMAND_FLAG_APPLY is NOT set then returns + * the first unused index but does NOT mark the banner as created. + * returns 0xFF on failure. + * + * rct2: 0x006BA278 + */ + sint32 create_new_banner(uint8 flags) + { + sint32 banner_index = 0; + for (; banner_index < MAX_BANNERS; banner_index++) { + if (gBanners[banner_index].type == BANNER_NULL) { + break; + } + } + + if (banner_index == MAX_BANNERS) { + gGameCommandErrorText = STR_TOO_MANY_BANNERS_IN_GAME; + return BANNER_NULL; + } + + if (flags & GAME_COMMAND_FLAG_APPLY) { + rct_banner* banner = &gBanners[banner_index]; + + banner->flags = 0; + banner->type = 0; + banner->string_idx = STR_DEFAULT_SIGN; + banner->colour = 2; + banner->text_colour = 2; + } + return banner_index; + } + + rct_map_element *banner_get_map_element(sint32 bannerIndex) + { + rct_banner *banner = &gBanners[bannerIndex]; + rct_map_element *mapElement = map_get_first_element_at(banner->x, banner->y); + do { + if (map_element_get_banner_index(mapElement) == bannerIndex) { + return mapElement; + } + } while (!map_element_is_last_for_tile(mapElement++)); + return NULL; + } + + /** + * + * rct2: 0x006B7EAB + */ + static sint32 banner_get_ride_index_at(sint32 x, sint32 y, sint32 z) + { + rct_map_element *mapElement; + rct_ride *ride; + sint32 rideIndex, resultRideIndex; + + resultRideIndex = -1; + mapElement = map_get_first_element_at(x >> 5, y >> 5); + do { + if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_TRACK) + continue; + + rideIndex = mapElement->properties.track.ride_index; + ride = get_ride(rideIndex); + if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) + continue; + + if ((mapElement->clearance_height * 8) + 32 <= z) + continue; + + resultRideIndex = rideIndex; + } while (!map_element_is_last_for_tile(mapElement++)); + + return resultRideIndex; + } + + /** + * + * rct2: 0x006B7D86 + */ + sint32 banner_get_closest_ride_index(sint32 x, sint32 y, sint32 z) + { + uint32 i, rideIndex; + rct_ride *ride; + + static const rct_xy16 NeighbourCheckOrder[] = { + { 32, 0 }, + { -32, 0 }, + { 0, 32 }, + { 0, -32 }, + { -32, +32 }, + { +32, -32 }, + { +32, +32 }, + { -32, +32 }, + { 0, 0 } + }; + + for (i = 0; i < Util::CountOf(NeighbourCheckOrder); i++) { + rideIndex = banner_get_ride_index_at(x + NeighbourCheckOrder[i].x, y + NeighbourCheckOrder[i].y, z); + if (rideIndex != -1) { + return rideIndex; + } + } + + rideIndex = -1; + sint32 resultDistance = INT_MAX; + FOR_ALL_RIDES(i, ride) { + if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) + continue; + + uint16 xy = ride->overall_view; + if (xy == 0xFFFF) + continue; + + sint32 rideX = (xy & 0xFF) * 32; + sint32 rideY = (xy >> 8) * 32; + sint32 distance = abs(x - rideX) + abs(y - rideY); + if (distance < resultDistance) { + resultDistance = distance; + rideIndex = i; + } + } + + return rideIndex; + } + + void fix_banner_count() + { + for (sint32 banner_index = 0; banner_index < MAX_BANNERS; banner_index++) { + rct_map_element *map_element = banner_get_map_element(banner_index); + if (map_element == NULL) + gBanners[banner_index].type = BANNER_NULL; + } + } + + + /** + * + * rct2: 0x006BA058 + */ + void game_command_remove_banner(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) + { + sint32 x = *eax; + sint32 y = *ecx; + uint8 base_height = *edx; + uint8 banner_position = *edx >> 8; + uint8 flags = *ebx & 0xFF; + sint32 z = base_height * 8; + gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + gCommandPosition.x = x + 16; + gCommandPosition.y = y + 16; + gCommandPosition.z = z; + + if (!(flags & GAME_COMMAND_FLAG_GHOST) && game_is_paused() && !gCheatsBuildInPauseMode) { + gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; + *ebx = MONEY32_UNDEFINED; + return; + } + + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode && !map_is_location_owned(x, y, z - 16)) { + *ebx = MONEY32_UNDEFINED; + return; + } + + // Slight modification to the code so that it now checks height as well + // This was causing a bug with banners on two paths stacked. + rct_map_element* map_element = map_get_banner_element_at(x / 32, y / 32, base_height, banner_position); + if (map_element == NULL) { + *ebx = MONEY32_UNDEFINED; + return; + } + + rct_banner *banner = &gBanners[map_element->properties.banner.index]; + rct_scenery_entry *scenery_entry = get_banner_entry(banner->type); + money32 refund = 0; + if (scenery_entry != NULL && scenery_entry != (rct_scenery_entry *)-1) { + refund = -((scenery_entry->banner.price * 3) / 4); + } + + if (flags & GAME_COMMAND_FLAG_APPLY) { + if (gGameCommandNestLevel == 1 && !(*ebx & GAME_COMMAND_FLAG_GHOST)) { + rct_xyz16 coord; + coord.x = x + 16; + coord.y = y + 16; + coord.z = map_element_height(coord.x, coord.y); + network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); + } + + map_element_remove_banner_entry(map_element); + map_invalidate_tile_zoom1(x, y, z, z + 32); + map_element_remove(map_element); + } + + *ebx = refund; + if (gParkFlags & PARK_FLAGS_NO_MONEY) { + *ebx = 0; + } + } + + + /** + * + * rct2: 0x006BA16A + */ + void game_command_set_banner_colour(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) + { + gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + sint32 x = *eax; + sint32 y = *ecx; + uint8 base_height = *edx; + uint8 banner_position = *edx >> 8; + uint8 colour = *ebp; + sint32 z = (base_height * 8); + gCommandPosition.x = x + 16; + gCommandPosition.y = y + 16; + gCommandPosition.z = z; + + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) { + if (!map_is_location_owned(x, y, z - 16)) { + *ebx = MONEY32_UNDEFINED; + return; + } + } + + if (*ebx & GAME_COMMAND_FLAG_APPLY) { + rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32); + + 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); + } + gBanners[map_element->properties.banner.index].colour = colour; + map_invalidate_tile_zoom1(x, y, z, z + 32); + } + + *ebx = 0; + } + + /** + * + * rct2: 0x006B9E6D + */ + void game_command_place_banner(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) + { + sint32 x = (uint16)*eax; + sint32 y = (uint16)*ecx; + uint8 base_height = *edx; + uint8 edge = *edx >> 8; + uint8 colour = *edi; + uint8 type = *ebx >> 8; + gCommandPosition.x = x + 16; + gCommandPosition.y = y + 16; + gCommandPosition.z = base_height * 16; + gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + if (game_is_paused() && !gCheatsBuildInPauseMode) { + gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; + *ebx = MONEY32_UNDEFINED; + return; + } + + if (!map_check_free_elements_and_reorganise(1)) { + *ebx = MONEY32_UNDEFINED; + return; + } + + if (x >= 8192 || y >= 8192) { + *ebx = MONEY32_UNDEFINED; + return; + } + + rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32); + sint32 dl = base_height * 2; + sint32 ch = (base_height - 1) * 2; + + bool pathFound = false; + do { + if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_PATH) + continue; + + if (map_element->base_height != dl && map_element->base_height != ch) + continue; + + if (!(map_element->properties.path.edges & (1 << edge))) + continue; + + pathFound = true; + break; + } while (!map_element_is_last_for_tile(map_element++)); + + if (pathFound == false) { + gGameCommandErrorText = STR_CAN_ONLY_BE_BUILT_ACROSS_PATHS; + *ebx = MONEY32_UNDEFINED; + return; + } + + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode && !map_is_location_owned(x, y, base_height * 16)) { + *ebx = MONEY32_UNDEFINED; + return; + } + map_element = map_get_first_element_at(x / 32, y / 32); + dl = (base_height + 1) * 2; + + // Check to see if there is a banner in the way + do { + if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_BANNER) + continue; + + if (map_element->base_height != dl) + continue; + + if ((map_element->properties.banner.position & 0x3) != edge) + continue; + + gGameCommandErrorText = STR_BANNER_SIGN_IN_THE_WAY; + *ebx = MONEY32_UNDEFINED; + return; + } while (!map_element_is_last_for_tile(map_element++)); + + sint32 banner_index = create_new_banner(*ebx); + if (banner_index == BANNER_NULL) { + *ebx = MONEY32_UNDEFINED; + return; + } + *edi = banner_index; + if (*ebx & GAME_COMMAND_FLAG_APPLY) { + if (gGameCommandNestLevel == 1 && !(*ebx & GAME_COMMAND_FLAG_GHOST)) { + rct_xyz16 coord; + coord.x = x + 16; + coord.y = y + 16; + coord.z = map_element_height(coord.x, coord.y); + network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); + } + + rct_map_element* new_map_element = map_element_insert(x / 32, y / 32, (base_height + 1) * 2, 0); + assert(new_map_element != NULL); + gBanners[banner_index].type = type; + gBanners[banner_index].colour = colour; + gBanners[banner_index].x = x / 32; + gBanners[banner_index].y = y / 32; + new_map_element->type = MAP_ELEMENT_TYPE_BANNER; + new_map_element->clearance_height = new_map_element->base_height + 2; + new_map_element->properties.banner.position = edge; + new_map_element->properties.banner.flags = 0xFF; + new_map_element->properties.banner.unused = 0; + new_map_element->properties.banner.index = banner_index; + if (*ebx & GAME_COMMAND_FLAG_GHOST) { + new_map_element->flags |= MAP_ELEMENT_FLAG_GHOST; + } + map_invalidate_tile_full(x, y); + map_animation_create(0x0A, x, y, new_map_element->base_height); + } + rct_scenery_entry *scenery_entry = (rct_scenery_entry*)object_entry_groups[OBJECT_TYPE_BANNERS].chunks[type]; + *ebx = scenery_entry->banner.price; + if (gParkFlags & PARK_FLAGS_NO_MONEY) { + *ebx = 0; + } + } + + void game_command_set_banner_name(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { + static char newName[128]; + + if ((*ecx >= MAX_BANNERS) || (*ecx < 0)) + { + log_warning("Invalid game command for setting banner name, banner id = %d", *ecx); + *ebx = MONEY32_UNDEFINED; + return; + } + rct_banner* banner = &gBanners[*ecx]; + + sint32 nameChunkIndex = *eax & 0xFFFF; + + gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS; + sint32 nameChunkOffset = nameChunkIndex - 1; + if (nameChunkOffset < 0) + nameChunkOffset = 2; + nameChunkOffset *= 12; + nameChunkOffset = min(nameChunkOffset, (sint32)Util::CountOf(newName) - 12); + memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 0), edx, sizeof(uint32)); + memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 4), ebp, sizeof(uint32)); + memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 8), edi, sizeof(uint32)); + + if (nameChunkIndex != 0) { + *ebx = 0; + return; + } + + if (!(*ebx & GAME_COMMAND_FLAG_APPLY)) { + *ebx = 0; + return; + } + + utf8 *buffer = gCommonStringFormatBuffer; + utf8 *dst = buffer; + dst = utf8_write_codepoint(dst, FORMAT_COLOUR_CODE_START + banner->text_colour); + safe_strcpy(dst, newName, 32); + + rct_string_id stringId = user_string_allocate(128, buffer); + if (stringId) { + rct_string_id prev_string_id = banner->string_idx; + banner->string_idx = stringId; + user_string_free(prev_string_id); + rct_window* w = window_bring_to_front_by_number(WC_BANNER, *ecx); + if (w) { + window_invalidate(w); + } + } + else { + gGameCommandErrorText = STR_ERR_CANT_SET_BANNER_TEXT; + *ebx = MONEY32_UNDEFINED; + return; + } + + *ebx = 0; + } + + void game_command_set_banner_style(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { + if ((*ecx >= MAX_BANNERS) || (*ecx < 0)) + { + gGameCommandErrorText = STR_INVALID_SELECTION_OF_OBJECTS; + *ebx = MONEY32_UNDEFINED; + return; + } + + if (!(*ebx & GAME_COMMAND_FLAG_APPLY)) { + *ebx = 0; + return; + } + + rct_banner* banner = &gBanners[*ecx]; + + banner->colour = (uint8)*edx; + banner->text_colour = (uint8)*edi; + banner->flags = (uint8)*ebp; + + uint8 bannerIndex = *ecx & 0xFF; + + sint32 x = banner->x << 5; + sint32 y = banner->y << 5; + + rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32); + bool bannerFound = false; + do { + if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_BANNER) + continue; + + if (map_element->properties.banner.index != bannerIndex) + continue; + + bannerFound = true; + break; + } while (!map_element_is_last_for_tile(map_element++)); + + if (bannerFound == false) { + *ebx = MONEY32_UNDEFINED; + return; + } + + map_element->properties.banner.flags = 0xFF; + if (banner->flags & BANNER_FLAG_NO_ENTRY) { + map_element->properties.banner.flags &= ~(1 << map_element->properties.banner.position); + } + + sint32 colourCodepoint = FORMAT_COLOUR_CODE_START + banner->text_colour; + + utf8 buffer[256]; + format_string(buffer, 256, banner->string_idx, 0); + sint32 firstCodepoint = utf8_get_next(buffer, NULL); + if (firstCodepoint >= FORMAT_COLOUR_CODE_START && firstCodepoint <= FORMAT_COLOUR_CODE_END) { + utf8_write_codepoint(buffer, colourCodepoint); + } + else { + utf8_insert_codepoint(buffer, colourCodepoint); + } + + rct_string_id stringId = user_string_allocate(128, buffer); + if (stringId != 0) { + rct_string_id prev_string_id = banner->string_idx; + banner->string_idx = stringId; + user_string_free(prev_string_id); + rct_window* w = window_bring_to_front_by_number(WC_BANNER, *ecx); + if (w) { + window_invalidate(w); + } + } + else { + gGameCommandErrorText = STR_ERR_CANT_SET_BANNER_TEXT; + *ebx = MONEY32_UNDEFINED; + return; + } + + *ebx = 0; + } + +} diff --git a/src/openrct2/world/banner.h b/src/openrct2/world/banner.h index 003d711e18..aeee30d7f0 100644 --- a/src/openrct2/world/banner.h +++ b/src/openrct2/world/banner.h @@ -40,7 +40,7 @@ enum{ BANNER_FLAG_NO_ENTRY = (1 << 0), BANNER_FLAG_IS_LARGE_SCENERY = (1 << 1), BANNER_FLAG_LINKED_TO_RIDE = (1 << 2), - BANNER_FLAG_4 = (1 << 3) + BANNER_FLAG_IS_WALL = (1 << 3) }; extern rct_banner gBanners[MAX_BANNERS]; diff --git a/src/openrct2/world/map.c b/src/openrct2/world/map.c index f9f4c7c006..44fcc1eaa5 100644 --- a/src/openrct2/world/map.c +++ b/src/openrct2/world/map.c @@ -1089,69 +1089,6 @@ void game_command_remove_large_scenery(sint32* eax, sint32* ebx, sint32* ecx, si return; } -/** - * - * rct2: 0x006BA058 - */ -void game_command_remove_banner(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) -{ - sint32 x = *eax; - sint32 y = *ecx; - uint8 base_height = *edx; - uint8 banner_position = *edx >> 8; - uint8 flags = *ebx & 0xFF; - sint32 z = base_height * 8; - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = z; - - if(!(flags & GAME_COMMAND_FLAG_GHOST) && game_is_paused() && !gCheatsBuildInPauseMode){ - gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; - *ebx = MONEY32_UNDEFINED; - return; - } - - if(!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode && !map_is_location_owned(x, y, z - 16)){ - *ebx = MONEY32_UNDEFINED; - return; - } - - // Slight modification to the code so that it now checks height as well - // This was causing a bug with banners on two paths stacked. - rct_map_element* map_element = map_get_banner_element_at(x / 32, y / 32, base_height, banner_position); - if (map_element == NULL){ - *ebx = MONEY32_UNDEFINED; - return; - } - - rct_banner *banner = &gBanners[map_element->properties.banner.index]; - rct_scenery_entry *scenery_entry = get_banner_entry(banner->type); - money32 refund = 0; - if (scenery_entry != NULL && scenery_entry != (rct_scenery_entry *)-1) { - refund = -((scenery_entry->banner.price * 3) / 4); - } - - if (flags & GAME_COMMAND_FLAG_APPLY) { - if (gGameCommandNestLevel == 1 && !(*ebx & GAME_COMMAND_FLAG_GHOST)) { - rct_xyz16 coord; - coord.x = x + 16; - coord.y = y + 16; - coord.z = map_element_height(coord.x, coord.y); - network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); - } - - map_element_remove_banner_entry(map_element); - map_invalidate_tile_zoom1(x, y, z, z + 32); - map_element_remove(map_element); - } - - *ebx = refund; - if (gParkFlags & PARK_FLAGS_NO_MONEY) { - *ebx = 0; - } -} - /** * * rct2: 0x006E0F26 @@ -1287,61 +1224,6 @@ void game_command_set_large_scenery_colour(sint32* eax, sint32* ebx, sint32* ecx *ebx = 0; } -/** - * - * rct2: 0x006BA16A - */ -void game_command_set_banner_colour(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) -{ - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - sint32 x = *eax; - sint32 y = *ecx; - uint8 base_height = *edx; - uint8 banner_position = *edx >> 8; - uint8 colour = *ebp; - sint32 z = (base_height * 8); - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = z; - - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode){ - if (!map_is_location_owned(x, y, z - 16)){ - *ebx = MONEY32_UNDEFINED; - return; - } - } - - if(*ebx & GAME_COMMAND_FLAG_APPLY){ - rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32); - - 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); - } - gBanners[map_element->properties.banner.index].colour = colour; - map_invalidate_tile_zoom1(x, y, z, z + 32); - } - - *ebx = 0; -} - // This will cause clear scenery to remove paths // This should be a flag for the game command which can be set via a checkbox on the clear scenery window. // #define CLEAR_SCENERY_REMOVES_PATHS @@ -2746,126 +2628,6 @@ void game_command_set_water_height(sint32* eax, sint32* ebx, sint32* ecx, sint32 } } -/** - * - * rct2: 0x006B9E6D - */ -void game_command_place_banner(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) -{ - sint32 x = (uint16)*eax; - sint32 y = (uint16)*ecx; - uint8 base_height = *edx; - uint8 edge = *edx >> 8; - uint8 colour = *edi; - uint8 type = *ebx >> 8; - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = base_height * 16; - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - if (game_is_paused() && !gCheatsBuildInPauseMode) { - gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; - *ebx = MONEY32_UNDEFINED; - return; - } - - if (!map_check_free_elements_and_reorganise(1)) { - *ebx = MONEY32_UNDEFINED; - return; - } - - if (x >= 8192 || y >= 8192) { - *ebx = MONEY32_UNDEFINED; - return; - } - - rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32); - sint32 dl = base_height * 2; - sint32 ch = (base_height - 1) * 2; - - bool pathFound = false; - do { - if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_PATH) - continue; - - if (map_element->base_height != dl && map_element->base_height != ch) - continue; - - if (!(map_element->properties.path.edges & (1 << edge))) - continue; - - pathFound = true; - break; - } while (!map_element_is_last_for_tile(map_element++)); - - if (pathFound == false) { - gGameCommandErrorText = STR_CAN_ONLY_BE_BUILT_ACROSS_PATHS; - *ebx = MONEY32_UNDEFINED; - return; - } - - if(!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode && !map_is_location_owned(x, y, base_height * 16)){ - *ebx = MONEY32_UNDEFINED; - return; - } - map_element = map_get_first_element_at(x / 32, y / 32); - dl = (base_height + 1) * 2; - - // Check to see if there is a banner in the way - do { - if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_BANNER) - continue; - - if (map_element->base_height != dl) - continue; - - if ((map_element->properties.banner.position & 0x3) != edge) - continue; - - gGameCommandErrorText = STR_BANNER_SIGN_IN_THE_WAY; - *ebx = MONEY32_UNDEFINED; - return; - } while (!map_element_is_last_for_tile(map_element++)); - - sint32 banner_index = create_new_banner(*ebx); - if(banner_index == BANNER_NULL){ - *ebx = MONEY32_UNDEFINED; - return; - } - *edi = banner_index; - if(*ebx & GAME_COMMAND_FLAG_APPLY){ - if (gGameCommandNestLevel == 1 && !(*ebx & GAME_COMMAND_FLAG_GHOST)) { - rct_xyz16 coord; - coord.x = x + 16; - coord.y = y + 16; - coord.z = map_element_height(coord.x, coord.y); - network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); - } - - rct_map_element* new_map_element = map_element_insert(x / 32, y / 32, (base_height + 1) * 2, 0); - assert(new_map_element != NULL); - gBanners[banner_index].type = type; - gBanners[banner_index].colour = colour; - gBanners[banner_index].x = x / 32; - gBanners[banner_index].y = y / 32; - new_map_element->type = MAP_ELEMENT_TYPE_BANNER; - new_map_element->clearance_height = new_map_element->base_height + 2; - new_map_element->properties.banner.position = edge; - new_map_element->properties.banner.flags = 0xFF; - new_map_element->properties.banner.unused = 0; - new_map_element->properties.banner.index = banner_index; - if(*ebx & GAME_COMMAND_FLAG_GHOST){ - new_map_element->flags |= MAP_ELEMENT_FLAG_GHOST; - } - map_invalidate_tile_full(x, y); - map_animation_create(0x0A, x, y, new_map_element->base_height); - } - rct_scenery_entry *scenery_entry = (rct_scenery_entry*)object_entry_groups[OBJECT_TYPE_BANNERS].chunks[type]; - *ebx = scenery_entry->banner.price; - if(gParkFlags & PARK_FLAGS_NO_MONEY){ - *ebx = 0; - } -} - /** * * rct2: 0x006E0D6E, 0x006B8D88 @@ -4580,62 +4342,6 @@ void map_clear_all_elements() } } -void game_command_set_banner_name(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { - static char newName[128]; - - if ((*ecx >= MAX_BANNERS) || (*ecx < 0)) - { - log_warning("Invalid game command for setting banner name, banner id = %d", *ecx); - *ebx = MONEY32_UNDEFINED; - return; - } - rct_banner* banner = &gBanners[*ecx]; - - sint32 nameChunkIndex = *eax & 0xFFFF; - - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS; - sint32 nameChunkOffset = nameChunkIndex - 1; - if (nameChunkOffset < 0) - nameChunkOffset = 2; - nameChunkOffset *= 12; - nameChunkOffset = min(nameChunkOffset, countof(newName) - 12); - memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 0), edx, sizeof(uint32)); - memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 4), ebp, sizeof(uint32)); - memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 8), edi, sizeof(uint32)); - - if (nameChunkIndex != 0) { - *ebx = 0; - return; - } - - if (!(*ebx & GAME_COMMAND_FLAG_APPLY)) { - *ebx = 0; - return; - } - - utf8 *buffer = gCommonStringFormatBuffer; - utf8 *dst = buffer; - dst = utf8_write_codepoint(dst, FORMAT_COLOUR_CODE_START + banner->text_colour); - safe_strcpy(dst, newName, 32); - - rct_string_id stringId = user_string_allocate(128, buffer); - if (stringId) { - rct_string_id prev_string_id = banner->string_idx; - banner->string_idx = stringId; - user_string_free(prev_string_id); - rct_window* w = window_bring_to_front_by_number(WC_BANNER, *ecx); - if (w) { - window_invalidate(w); - } - } else { - gGameCommandErrorText = STR_ERR_CANT_SET_BANNER_TEXT; - *ebx = MONEY32_UNDEFINED; - return; - } - - *ebx = 0; -} - void game_command_set_sign_name(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { static char newName[128]; @@ -4705,82 +4411,6 @@ void game_command_set_sign_name(sint32* eax, sint32* ebx, sint32* ecx, sint32* e *ebx = 0; } -void game_command_set_banner_style(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { - if ((*ecx >= MAX_BANNERS) || (*ecx < 0)) - { - gGameCommandErrorText = STR_INVALID_SELECTION_OF_OBJECTS; - *ebx = MONEY32_UNDEFINED; - return; - } - - if (!(*ebx & GAME_COMMAND_FLAG_APPLY)) { - *ebx = 0; - return; - } - - rct_banner* banner = &gBanners[*ecx]; - - banner->colour = (uint8)*edx; - banner->text_colour = (uint8)*edi; - banner->flags = (uint8)*ebp; - - uint8 bannerIndex = *ecx & 0xFF; - - sint32 x = banner->x << 5; - sint32 y = banner->y << 5; - - rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32); - bool bannerFound = false; - do { - if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_BANNER) - continue; - - if (map_element->properties.banner.index != bannerIndex) - continue; - - bannerFound = true; - break; - } while (!map_element_is_last_for_tile(map_element++)); - - if (bannerFound == false) { - *ebx = MONEY32_UNDEFINED; - return; - } - - map_element->properties.banner.flags = 0xFF; - if (banner->flags & BANNER_FLAG_NO_ENTRY){ - map_element->properties.banner.flags &= ~(1 << map_element->properties.banner.position); - } - - sint32 colourCodepoint = FORMAT_COLOUR_CODE_START + banner->text_colour; - - utf8 buffer[256]; - format_string(buffer, 256, banner->string_idx, 0); - sint32 firstCodepoint = utf8_get_next(buffer, NULL); - if (firstCodepoint >= FORMAT_COLOUR_CODE_START && firstCodepoint <= FORMAT_COLOUR_CODE_END) { - utf8_write_codepoint(buffer, colourCodepoint); - } else { - utf8_insert_codepoint(buffer, colourCodepoint); - } - - rct_string_id stringId = user_string_allocate(128, buffer); - if (stringId != 0) { - rct_string_id prev_string_id = banner->string_idx; - banner->string_idx = stringId; - user_string_free(prev_string_id); - rct_window* w = window_bring_to_front_by_number(WC_BANNER, *ecx); - if (w) { - window_invalidate(w); - } - } else { - gGameCommandErrorText = STR_ERR_CANT_SET_BANNER_TEXT; - *ebx = MONEY32_UNDEFINED; - return; - } - - *ebx = 0; -} - void game_command_set_sign_style(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { uint8 bannerId = *ecx & 0xFF; rct_banner *banner = &gBanners[bannerId]; diff --git a/src/openrct2/world/wall.cpp b/src/openrct2/world/wall.cpp index 97cb3d039a..033979c107 100644 --- a/src/openrct2/world/wall.cpp +++ b/src/openrct2/world/wall.cpp @@ -476,7 +476,7 @@ static money32 WallPlace(uint8 wallType, rct_banner * banner = &gBanners[bannerIndex]; if (flags & GAME_COMMAND_FLAG_APPLY) { - banner->flags |= BANNER_FLAG_4; + banner->flags |= BANNER_FLAG_IS_WALL; banner->type = 0; banner->x = position.x / 32; banner->y = position.y / 32; From afafdba0b71d7943588f8791d715baa47133f3b4 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 11 Mar 2017 08:36:46 +0000 Subject: [PATCH 2/5] Refactor of game commands --- src/openrct2/world/banner.cpp | 755 +++++++++++++++++----------------- 1 file changed, 377 insertions(+), 378 deletions(-) diff --git a/src/openrct2/world/banner.cpp b/src/openrct2/world/banner.cpp index c2d41f732e..127ff855d3 100644 --- a/src/openrct2/world/banner.cpp +++ b/src/openrct2/world/banner.cpp @@ -32,6 +32,341 @@ extern "C" rct_banner gBanners[MAX_BANNERS]; +/** + * + * rct2: 0x006B7EAB + */ +static sint32 banner_get_ride_index_at(sint32 x, sint32 y, sint32 z) +{ + rct_map_element *mapElement; + rct_ride *ride; + sint32 rideIndex, resultRideIndex; + + resultRideIndex = -1; + mapElement = map_get_first_element_at(x >> 5, y >> 5); + do { + if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_TRACK) + continue; + + rideIndex = mapElement->properties.track.ride_index; + ride = get_ride(rideIndex); + if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) + continue; + + if ((mapElement->clearance_height * 8) + 32 <= z) + continue; + + resultRideIndex = rideIndex; + } while (!map_element_is_last_for_tile(mapElement++)); + + return resultRideIndex; +} + +static money32 BannerRemove(sint16 x, sint16 y, uint8 baseHeight, uint8 direction, uint8 flags) +{ + sint32 z = baseHeight * 8; + gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + gCommandPosition.x = x + 16; + gCommandPosition.y = y + 16; + gCommandPosition.z = z; + + if (!(flags & GAME_COMMAND_FLAG_GHOST) && game_is_paused() && !gCheatsBuildInPauseMode) { + gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; + return MONEY32_UNDEFINED; + } + + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode && !map_is_location_owned(x, y, z - 16)) { + return MONEY32_UNDEFINED; + } + + // Slight modification to the code so that it now checks height as well + // This was causing a bug with banners on two paths stacked. + rct_map_element* mapElement = map_get_banner_element_at(x / 32, y / 32, baseHeight, direction); + if (mapElement == NULL) { + return MONEY32_UNDEFINED; + } + + rct_banner *banner = &gBanners[mapElement->properties.banner.index]; + rct_scenery_entry *scenery_entry = get_banner_entry(banner->type); + money32 refund = 0; + if (scenery_entry != NULL && scenery_entry != (rct_scenery_entry *)-1) { + refund = -((scenery_entry->banner.price * 3) / 4); + } + + if (flags & GAME_COMMAND_FLAG_APPLY) { + if (gGameCommandNestLevel == 1 && !(flags & GAME_COMMAND_FLAG_GHOST)) { + rct_xyz16 coord; + coord.x = x + 16; + coord.y = y + 16; + coord.z = map_element_height(coord.x, coord.y); + network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); + } + + map_element_remove_banner_entry(mapElement); + map_invalidate_tile_zoom1(x, y, z, z + 32); + map_element_remove(mapElement); + } + + if (gParkFlags & PARK_FLAGS_NO_MONEY) { + refund = 0; + } + return refund; +} + +static money32 BannerSetColour(sint16 x, sint16 y, uint8 baseHeight, uint8 direction, uint8 colour, uint8 flags) +{ + gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + sint32 z = (baseHeight * 8); + gCommandPosition.x = x + 16; + gCommandPosition.y = y + 16; + gCommandPosition.z = z; + + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) { + if (!map_is_location_owned(x, y, z - 16)) { + return MONEY32_UNDEFINED; + } + } + + if (flags & GAME_COMMAND_FLAG_APPLY) { + rct_map_element* mapElement = map_get_first_element_at(x / 32, y / 32); + + bool found = false; + do { + if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_BANNER) + continue; + + if (mapElement->properties.banner.position != direction) + continue; + + found = true; + break; + } while (!map_element_is_last_for_tile(mapElement++)); + + if (found == false) { + return MONEY32_UNDEFINED; + } + + rct_window* window = window_find_by_number(WC_BANNER, mapElement->properties.banner.index); + if (window) { + window_invalidate(window); + } + gBanners[mapElement->properties.banner.index].colour = colour; + map_invalidate_tile_zoom1(x, y, z, z + 32); + } + + return 0; +} + +money32 BannerPlace(sint16 x, sint16 y, uint8 pathBaseHeight, uint8 direction, uint8 colour, uint8 type, uint8 *bannerIndex, uint8 flags) +{ + gCommandPosition.x = x + 16; + gCommandPosition.y = y + 16; + gCommandPosition.z = pathBaseHeight * 16; + gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + if (game_is_paused() && !gCheatsBuildInPauseMode) { + gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; + return MONEY32_UNDEFINED; + } + + if (!map_check_free_elements_and_reorganise(1)) { + return MONEY32_UNDEFINED; + } + + if (x >= 8192 || y >= 8192) { + return MONEY32_UNDEFINED; + } + + rct_map_element* mapElement = map_get_first_element_at(x / 32, y / 32); + + bool pathFound = false; + do { + if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_PATH) + continue; + + if (mapElement->base_height != pathBaseHeight * 2 && mapElement->base_height != (pathBaseHeight - 1) * 2) + continue; + + if (!(mapElement->properties.path.edges & (1 << direction))) + continue; + + pathFound = true; + break; + } while (!map_element_is_last_for_tile(mapElement++)); + + if (pathFound == false) { + gGameCommandErrorText = STR_CAN_ONLY_BE_BUILT_ACROSS_PATHS; + return MONEY32_UNDEFINED; + } + + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode && !map_is_location_owned(x, y, pathBaseHeight * 16)) { + return MONEY32_UNDEFINED; + } + + uint8 baseHeight = (pathBaseHeight + 1) * 2; + mapElement = map_get_banner_element_at(x / 32, y / 32, baseHeight, direction);// map_get_first_element_at(x / 32, y / 32); + if (mapElement != nullptr) { + gGameCommandErrorText = STR_BANNER_SIGN_IN_THE_WAY; + return MONEY32_UNDEFINED; + } + + *bannerIndex = create_new_banner(flags); + if (*bannerIndex == BANNER_NULL) { + return MONEY32_UNDEFINED; + } + + if (flags & GAME_COMMAND_FLAG_APPLY) { + if (gGameCommandNestLevel == 1 && !(flags & GAME_COMMAND_FLAG_GHOST)) { + rct_xyz16 coord; + coord.x = x + 16; + coord.y = y + 16; + coord.z = map_element_height(coord.x, coord.y); + network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); + } + + rct_map_element* new_map_element = map_element_insert(x / 32, y / 32, baseHeight, 0); + assert(new_map_element != NULL); + gBanners[*bannerIndex].type = type; + gBanners[*bannerIndex].colour = colour; + gBanners[*bannerIndex].x = x / 32; + gBanners[*bannerIndex].y = y / 32; + new_map_element->type = MAP_ELEMENT_TYPE_BANNER; + new_map_element->clearance_height = new_map_element->base_height + 2; + new_map_element->properties.banner.position = direction; + new_map_element->properties.banner.flags = 0xFF; + new_map_element->properties.banner.unused = 0; + new_map_element->properties.banner.index = *bannerIndex; + if (flags & GAME_COMMAND_FLAG_GHOST) { + new_map_element->flags |= MAP_ELEMENT_FLAG_GHOST; + } + map_invalidate_tile_full(x, y); + map_animation_create(0x0A, x, y, new_map_element->base_height); + } + + rct_scenery_entry *scenery_entry = (rct_scenery_entry*)object_entry_groups[OBJECT_TYPE_BANNERS].chunks[type]; + if (gParkFlags & PARK_FLAGS_NO_MONEY) { + return 0; + } + return scenery_entry->banner.price; +} + +static money32 BannerSetName(uint8 bannerIndex, uint16 nameChunkIndex, uint32 nameChunk1, uint32 nameChunk2, uint32 nameChunk3, uint8 flags) +{ + static char newName[128]; + + if (bannerIndex >= MAX_BANNERS) + { + log_warning("Invalid game command for setting banner name, banner id = %d", bannerIndex); + return MONEY32_UNDEFINED; + } + rct_banner* banner = &gBanners[bannerIndex]; + + gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS; + uint32 indexToOffset[3] = { + 24, + 12, + 0 + }; + + if (nameChunkIndex > Util::CountOf(indexToOffset)) { + log_warning("Invalid chunk index for setting banner name, banner id = %d, index = %d", bannerIndex, nameChunkIndex); + return MONEY32_UNDEFINED; + } + + uint32 nameChunkOffset = min(indexToOffset[nameChunkIndex], Util::CountOf(newName) - 12); + memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 0), &nameChunk1, sizeof(uint32)); + memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 4), &nameChunk2, sizeof(uint32)); + memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 8), &nameChunk3, sizeof(uint32)); + + if (nameChunkIndex != 0) { + return 0; + } + + if (!(flags & GAME_COMMAND_FLAG_APPLY)) { + return 0; + } + + utf8 *buffer = gCommonStringFormatBuffer; + utf8 *dst = buffer; + dst = utf8_write_codepoint(dst, FORMAT_COLOUR_CODE_START + banner->text_colour); + safe_strcpy(dst, newName, 32); + + rct_string_id stringId = user_string_allocate(128, buffer); + if (stringId) { + rct_string_id prevStringId = banner->string_idx; + banner->string_idx = stringId; + user_string_free(prevStringId); + rct_window* w = window_bring_to_front_by_number(WC_BANNER, bannerIndex); + if (w) { + window_invalidate(w); + } + } + else { + gGameCommandErrorText = STR_ERR_CANT_SET_BANNER_TEXT; + return MONEY32_UNDEFINED; + } + + return 0; +} + +static money32 BannerSetStyle(uint8 bannerIndex, uint8 colour, uint8 textColour, uint8 bannerFlags, uint8 flags) +{ + if (bannerIndex >= MAX_BANNERS) + { + gGameCommandErrorText = STR_INVALID_SELECTION_OF_OBJECTS; + return MONEY32_UNDEFINED; + } + + rct_banner* banner = &gBanners[bannerIndex]; + + rct_map_element* mapElement = banner_get_map_element(bannerIndex); + + if (mapElement == nullptr) { + return MONEY32_UNDEFINED; + } + + if (!(flags & GAME_COMMAND_FLAG_APPLY)) { + return 0; + } + + banner->colour = colour; + banner->text_colour = textColour; + banner->flags = bannerFlags; + + mapElement->properties.banner.flags = 0xFF; + if (banner->flags & BANNER_FLAG_NO_ENTRY) { + mapElement->properties.banner.flags &= ~(1 << mapElement->properties.banner.position); + } + + sint32 colourCodepoint = FORMAT_COLOUR_CODE_START + banner->text_colour; + + utf8 buffer[256]; + format_string(buffer, 256, banner->string_idx, 0); + sint32 firstCodepoint = utf8_get_next(buffer, NULL); + if (firstCodepoint >= FORMAT_COLOUR_CODE_START && firstCodepoint <= FORMAT_COLOUR_CODE_END) { + utf8_write_codepoint(buffer, colourCodepoint); + } + else { + utf8_insert_codepoint(buffer, colourCodepoint); + } + + rct_string_id stringId = user_string_allocate(128, buffer); + if (stringId != 0) { + rct_string_id prevStringId = banner->string_idx; + banner->string_idx = stringId; + user_string_free(prevStringId); + rct_window* w = window_bring_to_front_by_number(WC_BANNER, bannerIndex); + if (w) { + window_invalidate(w); + } + } + else { + gGameCommandErrorText = STR_ERR_CANT_SET_BANNER_TEXT; + return MONEY32_UNDEFINED; + } + + return 0; +} + extern "C" { /** @@ -91,36 +426,6 @@ extern "C" return NULL; } - /** - * - * rct2: 0x006B7EAB - */ - static sint32 banner_get_ride_index_at(sint32 x, sint32 y, sint32 z) - { - rct_map_element *mapElement; - rct_ride *ride; - sint32 rideIndex, resultRideIndex; - - resultRideIndex = -1; - mapElement = map_get_first_element_at(x >> 5, y >> 5); - do { - if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_TRACK) - continue; - - rideIndex = mapElement->properties.track.ride_index; - ride = get_ride(rideIndex); - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) - continue; - - if ((mapElement->clearance_height * 8) + 32 <= z) - continue; - - resultRideIndex = rideIndex; - } while (!map_element_is_last_for_tile(mapElement++)); - - return resultRideIndex; - } - /** * * rct2: 0x006B7D86 @@ -174,130 +479,41 @@ extern "C" void fix_banner_count() { for (sint32 banner_index = 0; banner_index < MAX_BANNERS; banner_index++) { - rct_map_element *map_element = banner_get_map_element(banner_index); - if (map_element == NULL) + rct_map_element *mapElement = banner_get_map_element(banner_index); + if (mapElement == NULL) gBanners[banner_index].type = BANNER_NULL; } } - /** * * rct2: 0x006BA058 */ void game_command_remove_banner(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { - sint32 x = *eax; - sint32 y = *ecx; - uint8 base_height = *edx; - uint8 banner_position = *edx >> 8; - uint8 flags = *ebx & 0xFF; - sint32 z = base_height * 8; - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = z; - - if (!(flags & GAME_COMMAND_FLAG_GHOST) && game_is_paused() && !gCheatsBuildInPauseMode) { - gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; - *ebx = MONEY32_UNDEFINED; - return; - } - - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode && !map_is_location_owned(x, y, z - 16)) { - *ebx = MONEY32_UNDEFINED; - return; - } - - // Slight modification to the code so that it now checks height as well - // This was causing a bug with banners on two paths stacked. - rct_map_element* map_element = map_get_banner_element_at(x / 32, y / 32, base_height, banner_position); - if (map_element == NULL) { - *ebx = MONEY32_UNDEFINED; - return; - } - - rct_banner *banner = &gBanners[map_element->properties.banner.index]; - rct_scenery_entry *scenery_entry = get_banner_entry(banner->type); - money32 refund = 0; - if (scenery_entry != NULL && scenery_entry != (rct_scenery_entry *)-1) { - refund = -((scenery_entry->banner.price * 3) / 4); - } - - if (flags & GAME_COMMAND_FLAG_APPLY) { - if (gGameCommandNestLevel == 1 && !(*ebx & GAME_COMMAND_FLAG_GHOST)) { - rct_xyz16 coord; - coord.x = x + 16; - coord.y = y + 16; - coord.z = map_element_height(coord.x, coord.y); - network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); - } - - map_element_remove_banner_entry(map_element); - map_invalidate_tile_zoom1(x, y, z, z + 32); - map_element_remove(map_element); - } - - *ebx = refund; - if (gParkFlags & PARK_FLAGS_NO_MONEY) { - *ebx = 0; - } + *ebx = BannerRemove( + *eax & 0xFFFF, + *ecx & 0xFFFF, + *edx & 0xFF, + (*edx >> 8) & 0xFF, + *ebx & 0xFF + ); } - /** * * rct2: 0x006BA16A */ void game_command_set_banner_colour(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - sint32 x = *eax; - sint32 y = *ecx; - uint8 base_height = *edx; - uint8 banner_position = *edx >> 8; - uint8 colour = *ebp; - sint32 z = (base_height * 8); - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = z; - - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) { - if (!map_is_location_owned(x, y, z - 16)) { - *ebx = MONEY32_UNDEFINED; - return; - } - } - - if (*ebx & GAME_COMMAND_FLAG_APPLY) { - rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32); - - 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); - } - gBanners[map_element->properties.banner.index].colour = colour; - map_invalidate_tile_zoom1(x, y, z, z + 32); - } - - *ebx = 0; + *ebx = BannerSetColour( + *eax & 0xFFFF, + *ecx & 0xFFFF, + *edx & 0xFF, + (*edx >> 8) & 0xFF, + *ebp & 0xFF, + *ebx & 0xFF + ); } /** @@ -306,253 +522,36 @@ extern "C" */ void game_command_place_banner(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { - sint32 x = (uint16)*eax; - sint32 y = (uint16)*ecx; - uint8 base_height = *edx; - uint8 edge = *edx >> 8; - uint8 colour = *edi; - uint8 type = *ebx >> 8; - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = base_height * 16; - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - if (game_is_paused() && !gCheatsBuildInPauseMode) { - gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; - *ebx = MONEY32_UNDEFINED; - return; - } - - if (!map_check_free_elements_and_reorganise(1)) { - *ebx = MONEY32_UNDEFINED; - return; - } - - if (x >= 8192 || y >= 8192) { - *ebx = MONEY32_UNDEFINED; - return; - } - - rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32); - sint32 dl = base_height * 2; - sint32 ch = (base_height - 1) * 2; - - bool pathFound = false; - do { - if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_PATH) - continue; - - if (map_element->base_height != dl && map_element->base_height != ch) - continue; - - if (!(map_element->properties.path.edges & (1 << edge))) - continue; - - pathFound = true; - break; - } while (!map_element_is_last_for_tile(map_element++)); - - if (pathFound == false) { - gGameCommandErrorText = STR_CAN_ONLY_BE_BUILT_ACROSS_PATHS; - *ebx = MONEY32_UNDEFINED; - return; - } - - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode && !map_is_location_owned(x, y, base_height * 16)) { - *ebx = MONEY32_UNDEFINED; - return; - } - map_element = map_get_first_element_at(x / 32, y / 32); - dl = (base_height + 1) * 2; - - // Check to see if there is a banner in the way - do { - if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_BANNER) - continue; - - if (map_element->base_height != dl) - continue; - - if ((map_element->properties.banner.position & 0x3) != edge) - continue; - - gGameCommandErrorText = STR_BANNER_SIGN_IN_THE_WAY; - *ebx = MONEY32_UNDEFINED; - return; - } while (!map_element_is_last_for_tile(map_element++)); - - sint32 banner_index = create_new_banner(*ebx); - if (banner_index == BANNER_NULL) { - *ebx = MONEY32_UNDEFINED; - return; - } - *edi = banner_index; - if (*ebx & GAME_COMMAND_FLAG_APPLY) { - if (gGameCommandNestLevel == 1 && !(*ebx & GAME_COMMAND_FLAG_GHOST)) { - rct_xyz16 coord; - coord.x = x + 16; - coord.y = y + 16; - coord.z = map_element_height(coord.x, coord.y); - network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); - } - - rct_map_element* new_map_element = map_element_insert(x / 32, y / 32, (base_height + 1) * 2, 0); - assert(new_map_element != NULL); - gBanners[banner_index].type = type; - gBanners[banner_index].colour = colour; - gBanners[banner_index].x = x / 32; - gBanners[banner_index].y = y / 32; - new_map_element->type = MAP_ELEMENT_TYPE_BANNER; - new_map_element->clearance_height = new_map_element->base_height + 2; - new_map_element->properties.banner.position = edge; - new_map_element->properties.banner.flags = 0xFF; - new_map_element->properties.banner.unused = 0; - new_map_element->properties.banner.index = banner_index; - if (*ebx & GAME_COMMAND_FLAG_GHOST) { - new_map_element->flags |= MAP_ELEMENT_FLAG_GHOST; - } - map_invalidate_tile_full(x, y); - map_animation_create(0x0A, x, y, new_map_element->base_height); - } - rct_scenery_entry *scenery_entry = (rct_scenery_entry*)object_entry_groups[OBJECT_TYPE_BANNERS].chunks[type]; - *ebx = scenery_entry->banner.price; - if (gParkFlags & PARK_FLAGS_NO_MONEY) { - *ebx = 0; - } + *ebx = BannerPlace( + *eax & 0xFFFF, + *ecx & 0xFFFF, + *edx & 0xFF, + (*edx >> 8) & 0xFF, + *ebp & 0xFF, + (*ebx >> 8) & 0xFF, + (uint8 *)edi, + *ebx & 0xFF + ); } void game_command_set_banner_name(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { - static char newName[128]; - - if ((*ecx >= MAX_BANNERS) || (*ecx < 0)) - { - log_warning("Invalid game command for setting banner name, banner id = %d", *ecx); - *ebx = MONEY32_UNDEFINED; - return; - } - rct_banner* banner = &gBanners[*ecx]; - - sint32 nameChunkIndex = *eax & 0xFFFF; - - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS; - sint32 nameChunkOffset = nameChunkIndex - 1; - if (nameChunkOffset < 0) - nameChunkOffset = 2; - nameChunkOffset *= 12; - nameChunkOffset = min(nameChunkOffset, (sint32)Util::CountOf(newName) - 12); - memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 0), edx, sizeof(uint32)); - memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 4), ebp, sizeof(uint32)); - memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 8), edi, sizeof(uint32)); - - if (nameChunkIndex != 0) { - *ebx = 0; - return; - } - - if (!(*ebx & GAME_COMMAND_FLAG_APPLY)) { - *ebx = 0; - return; - } - - utf8 *buffer = gCommonStringFormatBuffer; - utf8 *dst = buffer; - dst = utf8_write_codepoint(dst, FORMAT_COLOUR_CODE_START + banner->text_colour); - safe_strcpy(dst, newName, 32); - - rct_string_id stringId = user_string_allocate(128, buffer); - if (stringId) { - rct_string_id prev_string_id = banner->string_idx; - banner->string_idx = stringId; - user_string_free(prev_string_id); - rct_window* w = window_bring_to_front_by_number(WC_BANNER, *ecx); - if (w) { - window_invalidate(w); - } - } - else { - gGameCommandErrorText = STR_ERR_CANT_SET_BANNER_TEXT; - *ebx = MONEY32_UNDEFINED; - return; - } - - *ebx = 0; + *ebx = BannerSetName( + *ecx & 0xFF, + *eax & 0xFFFF, + *edx, + *ebp, + *edi, + *ebx & 0xFF + ); } void game_command_set_banner_style(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { - if ((*ecx >= MAX_BANNERS) || (*ecx < 0)) - { - gGameCommandErrorText = STR_INVALID_SELECTION_OF_OBJECTS; - *ebx = MONEY32_UNDEFINED; - return; - } - - if (!(*ebx & GAME_COMMAND_FLAG_APPLY)) { - *ebx = 0; - return; - } - - rct_banner* banner = &gBanners[*ecx]; - - banner->colour = (uint8)*edx; - banner->text_colour = (uint8)*edi; - banner->flags = (uint8)*ebp; - - uint8 bannerIndex = *ecx & 0xFF; - - sint32 x = banner->x << 5; - sint32 y = banner->y << 5; - - rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32); - bool bannerFound = false; - do { - if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_BANNER) - continue; - - if (map_element->properties.banner.index != bannerIndex) - continue; - - bannerFound = true; - break; - } while (!map_element_is_last_for_tile(map_element++)); - - if (bannerFound == false) { - *ebx = MONEY32_UNDEFINED; - return; - } - - map_element->properties.banner.flags = 0xFF; - if (banner->flags & BANNER_FLAG_NO_ENTRY) { - map_element->properties.banner.flags &= ~(1 << map_element->properties.banner.position); - } - - sint32 colourCodepoint = FORMAT_COLOUR_CODE_START + banner->text_colour; - - utf8 buffer[256]; - format_string(buffer, 256, banner->string_idx, 0); - sint32 firstCodepoint = utf8_get_next(buffer, NULL); - if (firstCodepoint >= FORMAT_COLOUR_CODE_START && firstCodepoint <= FORMAT_COLOUR_CODE_END) { - utf8_write_codepoint(buffer, colourCodepoint); - } - else { - utf8_insert_codepoint(buffer, colourCodepoint); - } - - rct_string_id stringId = user_string_allocate(128, buffer); - if (stringId != 0) { - rct_string_id prev_string_id = banner->string_idx; - banner->string_idx = stringId; - user_string_free(prev_string_id); - rct_window* w = window_bring_to_front_by_number(WC_BANNER, *ecx); - if (w) { - window_invalidate(w); - } - } - else { - gGameCommandErrorText = STR_ERR_CANT_SET_BANNER_TEXT; - *ebx = MONEY32_UNDEFINED; - return; - } - - *ebx = 0; + *ebx = BannerSetStyle( + *ecx & 0xFF, + *edx & 0xFF, + *edi & 0xFF, + *ebp & 0xFF, + *ebx & 0xFF + ); } - } From 5dbc82ab9960229f6cb1224f3a32a2d05a268f88 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 11 Mar 2017 10:29:23 +0000 Subject: [PATCH 3/5] Apply cpp coding style Fix warning Fix xcode Use math min, use correct caseing for non windows Fix more warnings Fix warning --- OpenRCT2.xcodeproj/project.pbxproj | 11 +- src/openrct2/world/banner.cpp | 260 ++++++++++++++++++----------- 2 files changed, 172 insertions(+), 99 deletions(-) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 13ff135cf6..eae891bf00 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -20,12 +20,14 @@ 656F6C8E1E45BFC200E0F770 /* Version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 656F6C8C1E45BFC200E0F770 /* Version.cpp */; }; 658F3D911E44A6C200388550 /* ParkImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 658F3D8F1E44A6C200388550 /* ParkImporter.cpp */; }; 6876808CD662C4B16392A9B4 /* Balloon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 437490DBD74ECF60C3363559 /* Balloon.cpp */; }; + 689149B0417A68D6765F09CD /* banner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEEAE6E8AC49B6F288E69B40 /* banner.cpp */; }; 791166FB1D7486EF005912EA /* NetworkServerAdvertiser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 791166F91D7486EF005912EA /* NetworkServerAdvertiser.cpp */; }; 7D02D519C9A56A1FB9854FE7 /* Climate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 242F470FE91956ACA4078F6A /* Climate.cpp */; }; 85060FD31D8C17CC00DFA2B3 /* track_data_old.c in Sources */ = {isa = PBXBuildFile; fileRef = 8594C05F1D885CF600235E93 /* track_data_old.c */; }; 8594C0601D885CF600235E93 /* track_data_old.c in Sources */ = {isa = PBXBuildFile; fileRef = 8594C05F1D885CF600235E93 /* track_data_old.c */; }; 85B468FC1D96822F000F1DB5 /* paint_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = 85B468FB1D96822F000F1DB5 /* paint_helpers.c */; }; 85B468FD1D96822F000F1DB5 /* paint_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = 85B468FB1D96822F000F1DB5 /* paint_helpers.c */; }; + 8DED2F20E0D63A1DCFCE0197 /* banner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEEAE6E8AC49B6F288E69B40 /* banner.cpp */; }; C606CCBE1DB4054000FE4015 /* compat.c in Sources */ = {isa = PBXBuildFile; fileRef = C606CCAB1DB4054000FE4015 /* compat.c */; }; C606CCBF1DB4054000FE4015 /* data.c in Sources */ = {isa = PBXBuildFile; fileRef = C606CCAC1DB4054000FE4015 /* data.c */; }; C606CCC01DB4054000FE4015 /* FunctionCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C606CCAE1DB4054000FE4015 /* FunctionCall.cpp */; }; @@ -415,6 +417,8 @@ D44272971CC81B3200D84D28 /* viewport.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271D61CC81B3200D84D28 /* viewport.c */; }; D44272981CC81B3200D84D28 /* water.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271D71CC81B3200D84D28 /* water.c */; }; D442729A1CC81B3200D84D28 /* banner.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271DA1CC81B3200D84D28 /* banner.c */; }; + D44272991CC81B3200D84D28 /* balloon.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271D91CC81B3200D84D28 /* balloon.c */; }; + D442729B1CC81B3200D84D28 /* climate.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271DC1CC81B3200D84D28 /* climate.c */; }; D442729C1CC81B3200D84D28 /* duck.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271DE1CC81B3200D84D28 /* duck.c */; }; D442729D1CC81B3200D84D28 /* footpath.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271E01CC81B3200D84D28 /* footpath.c */; }; D442729E1CC81B3200D84D28 /* fountain.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271E21CC81B3200D84D28 /* fountain.c */; }; @@ -994,6 +998,7 @@ D44271D61CC81B3200D84D28 /* viewport.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = viewport.c; sourceTree = ""; }; D44271D71CC81B3200D84D28 /* water.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = water.c; sourceTree = ""; }; D44271DA1CC81B3200D84D28 /* banner.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = banner.c; sourceTree = ""; }; + D44271D91CC81B3200D84D28 /* balloon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = balloon.c; sourceTree = ""; }; D44271DB1CC81B3200D84D28 /* banner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = banner.h; sourceTree = ""; }; D44271DE1CC81B3200D84D28 /* duck.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = duck.c; sourceTree = ""; }; D44271DF1CC81B3200D84D28 /* entrance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = entrance.h; sourceTree = ""; }; @@ -1243,6 +1248,7 @@ D4F5B5ED1DAD8A4300AB6075 /* Cursors.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cursors.cpp; sourceTree = ""; }; D4F5B5EE1DAD8A4300AB6075 /* Cursors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cursors.h; sourceTree = ""; }; EC3C3FED9FA55B65F65D706F /* Climate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Climate.h; sourceTree = ""; }; + DEEAE6E8AC49B6F288E69B40 /* banner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = banner.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -2044,6 +2050,8 @@ 242F470FE91956ACA4078F6A /* Climate.cpp */, 437490DBD74ECF60C3363559 /* Balloon.cpp */, D44271DA1CC81B3200D84D28 /* banner.c */, + DEEAE6E8AC49B6F288E69B40 /* banner.cpp */, + D44271D91CC81B3200D84D28 /* balloon.c */, D44271DB1CC81B3200D84D28 /* banner.h */, D44271DE1CC81B3200D84D28 /* duck.c */, D48ABAB91E71EBD500A3E39C /* entrance.cpp */, @@ -2693,6 +2701,7 @@ C64FDAAE1D6D9A2100F259B9 /* water_coaster.c in Sources */, 6876808CD662C4B16392A9B4 /* Balloon.cpp in Sources */, 7D02D519C9A56A1FB9854FE7 /* Climate.cpp in Sources */, + 689149B0417A68D6765F09CD /* banner.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2722,7 +2731,6 @@ C65A88921E1B1148000368D7 /* AudioChannel.cpp in Sources */, C686F91D1CDBC3B7009F9BFC /* multi_dimension_roller_coaster.c in Sources */, C686F8B31CDBC37E009F9BFC /* surface.c in Sources */, - D442729A1CC81B3200D84D28 /* banner.c in Sources */, C650B21C1CCABC4400B4D91C /* ConvertCommand.cpp in Sources */, D44272211CC81B3200D84D28 /* viewport_interaction.c in Sources */, D442721B1CC81B3200D84D28 /* graph.c in Sources */, @@ -3052,6 +3060,7 @@ D44272871CC81B3200D84D28 /* staff_list.c in Sources */, F61331C839858250899F1E9B /* Balloon.cpp in Sources */, F2CC500E17C9411FBA859888 /* Climate.cpp in Sources */, + 8DED2F20E0D63A1DCFCE0197 /* banner.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/openrct2/world/banner.cpp b/src/openrct2/world/banner.cpp index 127ff855d3..1bce717c4a 100644 --- a/src/openrct2/world/banner.cpp +++ b/src/openrct2/world/banner.cpp @@ -14,10 +14,11 @@ *****************************************************************************/ #pragma endregion -#include "../core/util.hpp" +#include "../core/Util.hpp" +#include "../core/Math.hpp" #include "../network/network.h" -extern "C" +extern "C" { #include "../game.h" #include "../localisation/localisation.h" @@ -44,7 +45,8 @@ static sint32 banner_get_ride_index_at(sint32 x, sint32 y, sint32 z) resultRideIndex = -1; mapElement = map_get_first_element_at(x >> 5, y >> 5); - do { + do + { if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_TRACK) continue; @@ -70,31 +72,37 @@ static money32 BannerRemove(sint16 x, sint16 y, uint8 baseHeight, uint8 directio gCommandPosition.y = y + 16; gCommandPosition.z = z; - if (!(flags & GAME_COMMAND_FLAG_GHOST) && game_is_paused() && !gCheatsBuildInPauseMode) { + if (!(flags & GAME_COMMAND_FLAG_GHOST) && game_is_paused() && !gCheatsBuildInPauseMode) + { gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; return MONEY32_UNDEFINED; } - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode && !map_is_location_owned(x, y, z - 16)) { + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode && !map_is_location_owned(x, y, z - 16)) + { return MONEY32_UNDEFINED; } // Slight modification to the code so that it now checks height as well // This was causing a bug with banners on two paths stacked. rct_map_element* mapElement = map_get_banner_element_at(x / 32, y / 32, baseHeight, direction); - if (mapElement == NULL) { + if (mapElement == nullptr) + { return MONEY32_UNDEFINED; } rct_banner *banner = &gBanners[mapElement->properties.banner.index]; - rct_scenery_entry *scenery_entry = get_banner_entry(banner->type); + rct_scenery_entry *bannerEntry = get_banner_entry(banner->type); money32 refund = 0; - if (scenery_entry != NULL && scenery_entry != (rct_scenery_entry *)-1) { - refund = -((scenery_entry->banner.price * 3) / 4); + if (bannerEntry != nullptr && bannerEntry != (rct_scenery_entry *)-1) + { + refund = -((bannerEntry->banner.price * 3) / 4); } - if (flags & GAME_COMMAND_FLAG_APPLY) { - if (gGameCommandNestLevel == 1 && !(flags & GAME_COMMAND_FLAG_GHOST)) { + if (flags & GAME_COMMAND_FLAG_APPLY) + { + if (gGameCommandNestLevel == 1 && !(flags & GAME_COMMAND_FLAG_GHOST)) + { rct_xyz16 coord; coord.x = x + 16; coord.y = y + 16; @@ -107,7 +115,8 @@ static money32 BannerRemove(sint16 x, sint16 y, uint8 baseHeight, uint8 directio map_element_remove(mapElement); } - if (gParkFlags & PARK_FLAGS_NO_MONEY) { + if (gParkFlags & PARK_FLAGS_NO_MONEY) + { refund = 0; } return refund; @@ -121,17 +130,21 @@ static money32 BannerSetColour(sint16 x, sint16 y, uint8 baseHeight, uint8 direc gCommandPosition.y = y + 16; gCommandPosition.z = z; - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) { - if (!map_is_location_owned(x, y, z - 16)) { + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) + { + if (!map_is_location_owned(x, y, z - 16)) + { return MONEY32_UNDEFINED; } } - if (flags & GAME_COMMAND_FLAG_APPLY) { + if (flags & GAME_COMMAND_FLAG_APPLY) + { rct_map_element* mapElement = map_get_first_element_at(x / 32, y / 32); bool found = false; - do { + do + { if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_BANNER) continue; @@ -142,12 +155,14 @@ static money32 BannerSetColour(sint16 x, sint16 y, uint8 baseHeight, uint8 direc break; } while (!map_element_is_last_for_tile(mapElement++)); - if (found == false) { + if (found == false) + { return MONEY32_UNDEFINED; } rct_window* window = window_find_by_number(WC_BANNER, mapElement->properties.banner.index); - if (window) { + if (window) + { window_invalidate(window); } gBanners[mapElement->properties.banner.index].colour = colour; @@ -157,29 +172,33 @@ static money32 BannerSetColour(sint16 x, sint16 y, uint8 baseHeight, uint8 direc return 0; } -money32 BannerPlace(sint16 x, sint16 y, uint8 pathBaseHeight, uint8 direction, uint8 colour, uint8 type, uint8 *bannerIndex, uint8 flags) +static money32 BannerPlace(sint16 x, sint16 y, uint8 pathBaseHeight, uint8 direction, uint8 colour, uint8 type, uint8 *bannerIndex, uint8 flags) { gCommandPosition.x = x + 16; gCommandPosition.y = y + 16; gCommandPosition.z = pathBaseHeight * 16; gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - if (game_is_paused() && !gCheatsBuildInPauseMode) { + if (game_is_paused() && !gCheatsBuildInPauseMode) + { gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; return MONEY32_UNDEFINED; } - if (!map_check_free_elements_and_reorganise(1)) { + if (!map_check_free_elements_and_reorganise(1)) + { return MONEY32_UNDEFINED; } - if (x >= 8192 || y >= 8192) { + if (x >= 256 * 32 || y >= 256 * 32) + { return MONEY32_UNDEFINED; } rct_map_element* mapElement = map_get_first_element_at(x / 32, y / 32); bool pathFound = false; - do { + do + { if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_PATH) continue; @@ -193,29 +212,37 @@ money32 BannerPlace(sint16 x, sint16 y, uint8 pathBaseHeight, uint8 direction, u break; } while (!map_element_is_last_for_tile(mapElement++)); - if (pathFound == false) { + if (pathFound == false) + { gGameCommandErrorText = STR_CAN_ONLY_BE_BUILT_ACROSS_PATHS; return MONEY32_UNDEFINED; } - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode && !map_is_location_owned(x, y, pathBaseHeight * 16)) { + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && + !gCheatsSandboxMode && + !map_is_location_owned(x, y, pathBaseHeight * 16)) + { return MONEY32_UNDEFINED; } uint8 baseHeight = (pathBaseHeight + 1) * 2; - mapElement = map_get_banner_element_at(x / 32, y / 32, baseHeight, direction);// map_get_first_element_at(x / 32, y / 32); - if (mapElement != nullptr) { + mapElement = map_get_banner_element_at(x / 32, y / 32, baseHeight, direction); + if (mapElement != nullptr) + { gGameCommandErrorText = STR_BANNER_SIGN_IN_THE_WAY; return MONEY32_UNDEFINED; } *bannerIndex = create_new_banner(flags); - if (*bannerIndex == BANNER_NULL) { + if (*bannerIndex == BANNER_NULL) + { return MONEY32_UNDEFINED; } - if (flags & GAME_COMMAND_FLAG_APPLY) { - if (gGameCommandNestLevel == 1 && !(flags & GAME_COMMAND_FLAG_GHOST)) { + if (flags & GAME_COMMAND_FLAG_APPLY) + { + if (gGameCommandNestLevel == 1 && !(flags & GAME_COMMAND_FLAG_GHOST)) + { rct_xyz16 coord; coord.x = x + 16; coord.y = y + 16; @@ -223,33 +250,45 @@ money32 BannerPlace(sint16 x, sint16 y, uint8 pathBaseHeight, uint8 direction, u network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); } - rct_map_element* new_map_element = map_element_insert(x / 32, y / 32, baseHeight, 0); - assert(new_map_element != NULL); + rct_map_element* newMapElement = map_element_insert(x / 32, y / 32, baseHeight, 0); + assert(newMapElement != nullptr); gBanners[*bannerIndex].type = type; gBanners[*bannerIndex].colour = colour; gBanners[*bannerIndex].x = x / 32; gBanners[*bannerIndex].y = y / 32; - new_map_element->type = MAP_ELEMENT_TYPE_BANNER; - new_map_element->clearance_height = new_map_element->base_height + 2; - new_map_element->properties.banner.position = direction; - new_map_element->properties.banner.flags = 0xFF; - new_map_element->properties.banner.unused = 0; - new_map_element->properties.banner.index = *bannerIndex; - if (flags & GAME_COMMAND_FLAG_GHOST) { - new_map_element->flags |= MAP_ELEMENT_FLAG_GHOST; + newMapElement->type = MAP_ELEMENT_TYPE_BANNER; + newMapElement->clearance_height = newMapElement->base_height + 2; + newMapElement->properties.banner.position = direction; + newMapElement->properties.banner.flags = 0xFF; + newMapElement->properties.banner.unused = 0; + newMapElement->properties.banner.index = *bannerIndex; + if (flags & GAME_COMMAND_FLAG_GHOST) + { + newMapElement->flags |= MAP_ELEMENT_FLAG_GHOST; } map_invalidate_tile_full(x, y); - map_animation_create(0x0A, x, y, new_map_element->base_height); + map_animation_create(MAP_ANIMATION_TYPE_BANNER, x, y, newMapElement->base_height); } - rct_scenery_entry *scenery_entry = (rct_scenery_entry*)object_entry_groups[OBJECT_TYPE_BANNERS].chunks[type]; - if (gParkFlags & PARK_FLAGS_NO_MONEY) { + rct_scenery_entry *bannerEntry = get_banner_entry(type); + if ((bannerEntry == nullptr) || (bannerEntry == (rct_scenery_entry *)-1)) + { + return MONEY32_UNDEFINED; + } + + if (gParkFlags & PARK_FLAGS_NO_MONEY) + { return 0; } - return scenery_entry->banner.price; + return bannerEntry->banner.price; } -static money32 BannerSetName(uint8 bannerIndex, uint16 nameChunkIndex, uint32 nameChunk1, uint32 nameChunk2, uint32 nameChunk3, uint8 flags) +static money32 BannerSetName(uint8 bannerIndex, + uint16 nameChunkIndex, + uint32 nameChunk1, + uint32 nameChunk2, + uint32 nameChunk3, + uint8 flags) { static char newName[128]; @@ -261,27 +300,26 @@ static money32 BannerSetName(uint8 bannerIndex, uint16 nameChunkIndex, uint32 na rct_banner* banner = &gBanners[bannerIndex]; gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS; - uint32 indexToOffset[3] = { - 24, - 12, - 0 - }; + size_t indexToOffset[3] = { 24, 12, 0 }; - if (nameChunkIndex > Util::CountOf(indexToOffset)) { + if (nameChunkIndex > Util::CountOf(indexToOffset)) + { log_warning("Invalid chunk index for setting banner name, banner id = %d, index = %d", bannerIndex, nameChunkIndex); return MONEY32_UNDEFINED; } - uint32 nameChunkOffset = min(indexToOffset[nameChunkIndex], Util::CountOf(newName) - 12); + size_t nameChunkOffset = Math::Min(indexToOffset[nameChunkIndex], Util::CountOf(newName) - 12); memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 0), &nameChunk1, sizeof(uint32)); memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 4), &nameChunk2, sizeof(uint32)); memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 8), &nameChunk3, sizeof(uint32)); - if (nameChunkIndex != 0) { + if (nameChunkIndex != 0) + { return 0; } - if (!(flags & GAME_COMMAND_FLAG_APPLY)) { + if (!(flags & GAME_COMMAND_FLAG_APPLY)) + { return 0; } @@ -291,16 +329,19 @@ static money32 BannerSetName(uint8 bannerIndex, uint16 nameChunkIndex, uint32 na safe_strcpy(dst, newName, 32); rct_string_id stringId = user_string_allocate(128, buffer); - if (stringId) { + if (stringId) + { rct_string_id prevStringId = banner->string_idx; banner->string_idx = stringId; user_string_free(prevStringId); rct_window* w = window_bring_to_front_by_number(WC_BANNER, bannerIndex); - if (w) { + if (w) + { window_invalidate(w); } } - else { + else + { gGameCommandErrorText = STR_ERR_CANT_SET_BANNER_TEXT; return MONEY32_UNDEFINED; } @@ -320,11 +361,13 @@ static money32 BannerSetStyle(uint8 bannerIndex, uint8 colour, uint8 textColour, rct_map_element* mapElement = banner_get_map_element(bannerIndex); - if (mapElement == nullptr) { + if (mapElement == nullptr) + { return MONEY32_UNDEFINED; } - if (!(flags & GAME_COMMAND_FLAG_APPLY)) { + if (!(flags & GAME_COMMAND_FLAG_APPLY)) + { return 0; } @@ -333,7 +376,8 @@ static money32 BannerSetStyle(uint8 bannerIndex, uint8 colour, uint8 textColour, banner->flags = bannerFlags; mapElement->properties.banner.flags = 0xFF; - if (banner->flags & BANNER_FLAG_NO_ENTRY) { + if (banner->flags & BANNER_FLAG_NO_ENTRY) + { mapElement->properties.banner.flags &= ~(1 << mapElement->properties.banner.position); } @@ -341,25 +385,30 @@ static money32 BannerSetStyle(uint8 bannerIndex, uint8 colour, uint8 textColour, utf8 buffer[256]; format_string(buffer, 256, banner->string_idx, 0); - sint32 firstCodepoint = utf8_get_next(buffer, NULL); - if (firstCodepoint >= FORMAT_COLOUR_CODE_START && firstCodepoint <= FORMAT_COLOUR_CODE_END) { + sint32 firstCodepoint = utf8_get_next(buffer, nullptr); + if (firstCodepoint >= FORMAT_COLOUR_CODE_START && firstCodepoint <= FORMAT_COLOUR_CODE_END) + { utf8_write_codepoint(buffer, colourCodepoint); } - else { + else + { utf8_insert_codepoint(buffer, colourCodepoint); } rct_string_id stringId = user_string_allocate(128, buffer); - if (stringId != 0) { + if (stringId != 0) + { rct_string_id prevStringId = banner->string_idx; banner->string_idx = stringId; user_string_free(prevStringId); rct_window* w = window_bring_to_front_by_number(WC_BANNER, bannerIndex); - if (w) { + if (w) + { window_invalidate(w); } } - else { + else + { gGameCommandErrorText = STR_ERR_CANT_SET_BANNER_TEXT; return MONEY32_UNDEFINED; } @@ -375,7 +424,8 @@ extern "C" */ void banner_init() { - for (sint32 i = 0; i < MAX_BANNERS; i++) { + for (sint32 i = 0; i < MAX_BANNERS; i++) + { gBanners[i].type = BANNER_NULL; } } @@ -390,20 +440,24 @@ extern "C" */ sint32 create_new_banner(uint8 flags) { - sint32 banner_index = 0; - for (; banner_index < MAX_BANNERS; banner_index++) { - if (gBanners[banner_index].type == BANNER_NULL) { + sint32 bannerIndex = 0; + for (; bannerIndex < MAX_BANNERS; bannerIndex++) + { + if (gBanners[bannerIndex].type == BANNER_NULL) + { break; } } - if (banner_index == MAX_BANNERS) { + if (bannerIndex == MAX_BANNERS) + { gGameCommandErrorText = STR_TOO_MANY_BANNERS_IN_GAME; return BANNER_NULL; } - if (flags & GAME_COMMAND_FLAG_APPLY) { - rct_banner* banner = &gBanners[banner_index]; + if (flags & GAME_COMMAND_FLAG_APPLY) + { + rct_banner* banner = &gBanners[bannerIndex]; banner->flags = 0; banner->type = 0; @@ -411,19 +465,21 @@ extern "C" banner->colour = 2; banner->text_colour = 2; } - return banner_index; + return bannerIndex; } rct_map_element *banner_get_map_element(sint32 bannerIndex) { rct_banner *banner = &gBanners[bannerIndex]; rct_map_element *mapElement = map_get_first_element_at(banner->x, banner->y); - do { - if (map_element_get_banner_index(mapElement) == bannerIndex) { + do + { + if (map_element_get_banner_index(mapElement) == bannerIndex) + { return mapElement; } } while (!map_element_is_last_for_tile(mapElement++)); - return NULL; + return nullptr; } /** @@ -432,10 +488,11 @@ extern "C" */ sint32 banner_get_closest_ride_index(sint32 x, sint32 y, sint32 z) { - uint32 i, rideIndex; + sint32 i, rideIndex; rct_ride *ride; - static const rct_xy16 NeighbourCheckOrder[] = { + static const rct_xy16 NeighbourCheckOrder[] = + { { 32, 0 }, { -32, 0 }, { 0, 32 }, @@ -447,16 +504,19 @@ extern "C" { 0, 0 } }; - for (i = 0; i < Util::CountOf(NeighbourCheckOrder); i++) { + for (i = 0; i < (sint32)Util::CountOf(NeighbourCheckOrder); i++) + { rideIndex = banner_get_ride_index_at(x + NeighbourCheckOrder[i].x, y + NeighbourCheckOrder[i].y, z); - if (rideIndex != -1) { + if (rideIndex != -1) + { return rideIndex; } } rideIndex = -1; sint32 resultDistance = INT_MAX; - FOR_ALL_RIDES(i, ride) { + FOR_ALL_RIDES(i, ride) + { if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) continue; @@ -467,7 +527,8 @@ extern "C" sint32 rideX = (xy & 0xFF) * 32; sint32 rideY = (xy >> 8) * 32; sint32 distance = abs(x - rideX) + abs(y - rideY); - if (distance < resultDistance) { + if (distance < resultDistance) + { resultDistance = distance; rideIndex = i; } @@ -478,17 +539,18 @@ extern "C" void fix_banner_count() { - for (sint32 banner_index = 0; banner_index < MAX_BANNERS; banner_index++) { - rct_map_element *mapElement = banner_get_map_element(banner_index); - if (mapElement == NULL) - gBanners[banner_index].type = BANNER_NULL; + for (sint32 bannerIndex = 0; bannerIndex < MAX_BANNERS; bannerIndex++) + { + rct_map_element *mapElement = banner_get_map_element(bannerIndex); + if (mapElement == nullptr) + gBanners[bannerIndex].type = BANNER_NULL; } } /** - * - * rct2: 0x006BA058 - */ + * + * rct2: 0x006BA058 + */ void game_command_remove_banner(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { *ebx = BannerRemove( @@ -501,9 +563,9 @@ extern "C" } /** - * - * rct2: 0x006BA16A - */ + * + * rct2: 0x006BA16A + */ void game_command_set_banner_colour(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { *ebx = BannerSetColour( @@ -517,9 +579,9 @@ extern "C" } /** - * - * rct2: 0x006B9E6D - */ + * + * rct2: 0x006B9E6D + */ void game_command_place_banner(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { *ebx = BannerPlace( @@ -534,7 +596,8 @@ extern "C" ); } - void game_command_set_banner_name(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { + void game_command_set_banner_name(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) + { *ebx = BannerSetName( *ecx & 0xFF, *eax & 0xFFFF, @@ -545,7 +608,8 @@ extern "C" ); } - void game_command_set_banner_style(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) { + void game_command_set_banner_style(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) + { *ebx = BannerSetStyle( *ecx & 0xFF, *edx & 0xFF, From 6878341214594e2349a8654aec0b9c1dc3d3c916 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 11 Mar 2017 11:55:06 +0000 Subject: [PATCH 4/5] Make review changes --- src/openrct2/interface/console.c | 2 +- src/openrct2/world/banner.cpp | 56 ++++++++++++++++++-------------- src/openrct2/world/banner.h | 2 +- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/openrct2/interface/console.c b/src/openrct2/interface/console.c index 8d7b42bdef..8462cddc42 100644 --- a/src/openrct2/interface/console.c +++ b/src/openrct2/interface/console.c @@ -1139,7 +1139,7 @@ static sint32 cc_reset_user_strings(const utf8 **argv, sint32 argc) static sint32 cc_fix_banner_count(const utf8 **argv, sint32 argc) { - fix_banner_count(); + banner_reset_broken_index(); return 0; } diff --git a/src/openrct2/world/banner.cpp b/src/openrct2/world/banner.cpp index 1bce717c4a..2033fac8bd 100644 --- a/src/openrct2/world/banner.cpp +++ b/src/openrct2/world/banner.cpp @@ -14,21 +14,22 @@ *****************************************************************************/ #pragma endregion -#include "../core/Util.hpp" #include "../core/Math.hpp" +#include "../core/Memory.hpp" +#include "../core/Util.hpp" +#include "../core/String.hpp" #include "../network/network.h" extern "C" { - #include "../game.h" - #include "../localisation/localisation.h" - #include "../ride/ride.h" - #include "../interface/window.h" - #include "../util/util.h" - #include "scenery.h" #include "banner.h" #include "map.h" #include "park.h" + #include "scenery.h" + #include "../game.h" + #include "../interface/window.h" + #include "../localisation/localisation.h" + #include "../ride/ride.h" } rct_banner gBanners[MAX_BANNERS]; @@ -161,7 +162,7 @@ static money32 BannerSetColour(sint16 x, sint16 y, uint8 baseHeight, uint8 direc } rct_window* window = window_find_by_number(WC_BANNER, mapElement->properties.banner.index); - if (window) + if (window != nullptr) { window_invalidate(window); } @@ -309,9 +310,9 @@ static money32 BannerSetName(uint8 bannerIndex, } size_t nameChunkOffset = Math::Min(indexToOffset[nameChunkIndex], Util::CountOf(newName) - 12); - memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 0), &nameChunk1, sizeof(uint32)); - memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 4), &nameChunk2, sizeof(uint32)); - memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 8), &nameChunk3, sizeof(uint32)); + Memory::Copy((uint32*)(&newName[0 + nameChunkOffset]), &nameChunk1, sizeof(uint32)); + Memory::Copy((uint32*)(&newName[4 + nameChunkOffset]), &nameChunk2, sizeof(uint32)); + Memory::Copy((uint32*)(&newName[8 + nameChunkOffset]), &nameChunk3, sizeof(uint32)); if (nameChunkIndex != 0) { @@ -326,16 +327,16 @@ static money32 BannerSetName(uint8 bannerIndex, utf8 *buffer = gCommonStringFormatBuffer; utf8 *dst = buffer; dst = utf8_write_codepoint(dst, FORMAT_COLOUR_CODE_START + banner->text_colour); - safe_strcpy(dst, newName, 32); + String::Set(dst, 256, newName, 32); rct_string_id stringId = user_string_allocate(128, buffer); - if (stringId) + if (stringId != 0) { rct_string_id prevStringId = banner->string_idx; banner->string_idx = stringId; user_string_free(prevStringId); rct_window* w = window_bring_to_front_by_number(WC_BANNER, bannerIndex); - if (w) + if (w != nullptr) { window_invalidate(w); } @@ -402,7 +403,7 @@ static money32 BannerSetStyle(uint8 bannerIndex, uint8 colour, uint8 textColour, banner->string_idx = stringId; user_string_free(prevStringId); rct_window* w = window_bring_to_front_by_number(WC_BANNER, bannerIndex); - if (w) + if (w != nullptr) { window_invalidate(w); } @@ -416,6 +417,18 @@ static money32 BannerSetStyle(uint8 bannerIndex, uint8 colour, uint8 textColour, return 0; } +static uint8 BannerGetNewIndex() { + uint8 bannerIndex = 0; + for (; bannerIndex < MAX_BANNERS; bannerIndex++) + { + if (gBanners[bannerIndex].type == BANNER_NULL) + { + return bannerIndex; + } + } + return BANNER_NULL; +} + extern "C" { /** @@ -440,16 +453,9 @@ extern "C" */ sint32 create_new_banner(uint8 flags) { - sint32 bannerIndex = 0; - for (; bannerIndex < MAX_BANNERS; bannerIndex++) - { - if (gBanners[bannerIndex].type == BANNER_NULL) - { - break; - } - } + uint8 bannerIndex = BannerGetNewIndex(); - if (bannerIndex == MAX_BANNERS) + if (bannerIndex == BANNER_NULL) { gGameCommandErrorText = STR_TOO_MANY_BANNERS_IN_GAME; return BANNER_NULL; @@ -537,7 +543,7 @@ extern "C" return rideIndex; } - void fix_banner_count() + void banner_reset_broken_index() { for (sint32 bannerIndex = 0; bannerIndex < MAX_BANNERS; bannerIndex++) { diff --git a/src/openrct2/world/banner.h b/src/openrct2/world/banner.h index aeee30d7f0..24f19f8dab 100644 --- a/src/openrct2/world/banner.h +++ b/src/openrct2/world/banner.h @@ -49,7 +49,7 @@ void banner_init(); sint32 create_new_banner(uint8 flags); rct_map_element *banner_get_map_element(sint32 bannerIndex); sint32 banner_get_closest_ride_index(sint32 x, sint32 y, sint32 z); -void fix_banner_count(); +void banner_reset_broken_index(); void game_command_callback_place_banner(sint32 eax, sint32 ebx, sint32 ecx, sint32 edx, sint32 esi, sint32 edi, sint32 ebp); #endif From 132721128e0b4264b2e8516d2bc4ff27927a1fa7 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 13 Mar 2017 21:47:43 +0000 Subject: [PATCH 5/5] Create function for map_can_build_at --- src/openrct2/world/banner.cpp | 16 ++++++---------- src/openrct2/world/map.c | 11 +++++++++++ src/openrct2/world/map.h | 1 + 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/openrct2/world/banner.cpp b/src/openrct2/world/banner.cpp index 2033fac8bd..acb576f075 100644 --- a/src/openrct2/world/banner.cpp +++ b/src/openrct2/world/banner.cpp @@ -79,7 +79,7 @@ static money32 BannerRemove(sint16 x, sint16 y, uint8 baseHeight, uint8 directio return MONEY32_UNDEFINED; } - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode && !map_is_location_owned(x, y, z - 16)) + if (!map_can_build_at(x, y, z - 16)) { return MONEY32_UNDEFINED; } @@ -131,13 +131,11 @@ static money32 BannerSetColour(sint16 x, sint16 y, uint8 baseHeight, uint8 direc gCommandPosition.y = y + 16; gCommandPosition.z = z; - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) + if (!map_can_build_at(x, y, z - 16)) { - if (!map_is_location_owned(x, y, z - 16)) - { - return MONEY32_UNDEFINED; - } + return MONEY32_UNDEFINED; } + if (flags & GAME_COMMAND_FLAG_APPLY) { @@ -190,7 +188,7 @@ static money32 BannerPlace(sint16 x, sint16 y, uint8 pathBaseHeight, uint8 direc return MONEY32_UNDEFINED; } - if (x >= 256 * 32 || y >= 256 * 32) + if (!map_is_location_valid(x, y)) { return MONEY32_UNDEFINED; } @@ -219,9 +217,7 @@ static money32 BannerPlace(sint16 x, sint16 y, uint8 pathBaseHeight, uint8 direc return MONEY32_UNDEFINED; } - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && - !gCheatsSandboxMode && - !map_is_location_owned(x, y, pathBaseHeight * 16)) + if (!map_can_build_at(x, y, pathBaseHeight * 16)) { return MONEY32_UNDEFINED; } diff --git a/src/openrct2/world/map.c b/src/openrct2/world/map.c index 44fcc1eaa5..391f8aede6 100644 --- a/src/openrct2/world/map.c +++ b/src/openrct2/world/map.c @@ -788,6 +788,17 @@ bool map_is_location_valid(sint32 x, sint32 y) return false; } +bool map_can_build_at(sint32 x, sint32 y, sint32 z) +{ + if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) + return true; + if (gCheatsSandboxMode) + return true; + if (map_is_location_owned(x, y, z)) + return true; + return false; +} + /** * * rct2: 0x00664F72 diff --git a/src/openrct2/world/map.h b/src/openrct2/world/map.h index ca88007207..ad8833559d 100644 --- a/src/openrct2/world/map.h +++ b/src/openrct2/world/map.h @@ -436,6 +436,7 @@ void map_remove_provisional_elements(); void map_restore_provisional_elements(); void map_update_path_wide_flags(); bool map_is_location_valid(sint32 x, sint32 y); +bool map_can_build_at(sint32 x, sint32 y, sint32 z); bool map_is_location_owned(sint32 x, sint32 y, sint32 z); bool map_is_location_in_park(sint32 x, sint32 y); bool map_is_location_owned_or_has_rights(sint32 x, sint32 y);