From 6c8c5a157f61a8e57705f10e7455aefa23d36d1d Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 18 Nov 2015 17:48:14 +0000 Subject: [PATCH 01/14] Fix #2335. Increase land window size to show price correctly. --- src/windows/land.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/windows/land.c b/src/windows/land.c index 066c435944..f97044bcea 100644 --- a/src/windows/land.c +++ b/src/windows/land.c @@ -45,7 +45,7 @@ enum WINDOW_LAND_WIDGET_IDX { }; static rct_widget window_land_widgets[] = { - { WWT_FRAME, 0, 0, 97, 0, 143, -1, STR_NONE }, // panel / background + { WWT_FRAME, 0, 0, 97, 0, 159, -1, STR_NONE }, // panel / background { WWT_CAPTION, 0, 1, 96, 1, 14, STR_LAND, STR_WINDOW_TITLE_TIP }, // title bar { WWT_CLOSEBOX, 0, 85, 95, 2, 13, 824, STR_CLOSE_WINDOW_TIP }, // close x button @@ -133,7 +133,7 @@ void window_land_open() if (window_find_by_class(WC_LAND) != NULL) return; - window = window_create(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) - 98, 29, 98, 144, &window_land_events, WC_LAND, 0); + window = window_create(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) - 98, 29, 98, 160, &window_land_events, WC_LAND, 0); window->widgets = window_land_widgets; window->enabled_widgets = (1 << WIDX_CLOSE) | From e05475cb385d1a6ea28759a13de3867bd4db0a96 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 18 Nov 2015 22:32:23 +0000 Subject: [PATCH 02/14] Fix #2342. Accidentally disabled pause mode building for large scenery --- src/world/map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/map.c b/src/world/map.c index d1b53ad79e..8f4f588a45 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -3137,7 +3137,7 @@ void game_command_place_large_scenery(int* eax, int* ebx, int* ecx, int* edx, in // Supports cost RCT2_GLOBAL(0x00F4389A, money32) = 0; - if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) != 0 && gConfigCheat.build_in_pause_mode) { + if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) != 0 && !gConfigCheat.build_in_pause_mode) { RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; *ebx = MONEY32_UNDEFINED; return; From 67b6aa7513341a2b8b3b3faa001a90837755c542 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 18 Nov 2015 23:19:25 +0000 Subject: [PATCH 03/14] fix #2330: Clear button in Object Selector doesn't refresh item list --- src/windows/editor_object_selection.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/windows/editor_object_selection.c b/src/windows/editor_object_selection.c index f5eecca514..04bda016a1 100644 --- a/src/windows/editor_object_selection.c +++ b/src/windows/editor_object_selection.c @@ -861,9 +861,9 @@ static void window_editor_object_selection_mouseup(rct_window *w, int widgetInde break; case WIDX_FILTER_CLEAR_BUTTON: memset(_filter_string, 0, sizeof(_filter_string)); - + filter_update_counts(); w->scrolls->v_top = 0; - + visible_list_refresh(w); window_invalidate(w); break; case WIDX_LIST_SORT_TYPE: From bd262d9c59017c8413b2fd3559b3231a6ca3721f Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Fri, 20 Nov 2015 17:12:26 +0000 Subject: [PATCH 04/14] Fix #2308. ShopItem was accidentally passed into new_thought instead of thought_type --- src/peep/peep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/peep/peep.c b/src/peep/peep.c index e714c8de93..287848fe4d 100644 --- a/src/peep/peep.c +++ b/src/peep/peep.c @@ -1768,7 +1768,7 @@ static void peep_update_ride_sub_state_0(rct_peep* peep){ } if (ride->price > peep->cash_in_pocket){ - peep_insert_new_thought(peep, 0, peep->current_ride); + peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_CANT_AFFORD_0, peep->current_ride); if (peep->destination_tolerence == 0){ remove_peep_from_queue(peep); peep_decrement_num_riders(peep); @@ -7983,7 +7983,7 @@ loc_69B119: if (value > ((money16)(scenario_rand() & 0x07))) { // "I'm not paying that much for x" uint8 thought_type = (shopItem >= 32 ? (PEEP_THOUGHT_TYPE_PHOTO2_MUCH + (shopItem - 32)) : (PEEP_THOUGHT_TYPE_BALLOON_MUCH + shopItem)); - peep_insert_new_thought(peep, shopItem, rideIndex); + peep_insert_new_thought(peep, thought_type, rideIndex); return 0; } } From 5ef10f5050bbc3494e4d4eae6b12db558aa01778 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Fri, 20 Nov 2015 18:48:40 +0000 Subject: [PATCH 05/14] fix memory leaks in JSON object creation for multiplayer --- src/network/network.cpp | 44 ++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/network/network.cpp b/src/network/network.cpp index 8c566d4ff1..d4f2e2923a 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -860,8 +860,8 @@ void Network::AdvertiseRegister() request.method = HTTP_METHOD_POST; json_t *body = json_object(); - json_object_set(body, "key", json_string(advertise_key.c_str())); - json_object_set(body, "port", json_integer(listening_port)); + json_object_set_new(body, "key", json_string(advertise_key.c_str())); + json_object_set_new(body, "port", json_integer(listening_port)); request.body = body; http_request_json_async(&request, [](http_json_response *response) -> void { @@ -904,21 +904,21 @@ void Network::AdvertiseHeartbeat() request.method = HTTP_METHOD_PUT; json_t *body = json_object(); - json_object_set(body, "token", json_string(advertise_token.c_str())); - json_object_set(body, "players", json_integer(network_get_num_players())); + json_object_set_new(body, "token", json_string(advertise_token.c_str())); + json_object_set_new(body, "players", json_integer(network_get_num_players())); json_t *gameInfo = json_object(); - json_object_set(gameInfo, "mapSize", json_integer(RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint8) - 2)); - json_object_set(gameInfo, "day", json_integer(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_TICKS, uint16))); - json_object_set(gameInfo, "month", json_integer(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint16))); - json_object_set(gameInfo, "guests", json_integer(RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16))); - json_object_set(gameInfo, "parkValue", json_integer(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_VALUE, money32))); + json_object_set_new(gameInfo, "mapSize", json_integer(RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint8) - 2)); + json_object_set_new(gameInfo, "day", json_integer(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_TICKS, uint16))); + json_object_set_new(gameInfo, "month", json_integer(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint16))); + json_object_set_new(gameInfo, "guests", json_integer(RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16))); + json_object_set_new(gameInfo, "parkValue", json_integer(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_VALUE, money32))); if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY)) { money32 cash = DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, money32)); - json_object_set(gameInfo, "cash", json_integer(cash)); + json_object_set_new(gameInfo, "cash", json_integer(cash)); } - json_object_set(body, "gameInfo", gameInfo); + json_object_set_new(body, "gameInfo", gameInfo); request.body = body; gNetwork.last_heartbeat_time = SDL_GetTicks(); @@ -1084,20 +1084,20 @@ void Network::Server_Send_GAMEINFO(NetworkConnection& connection) *packet << (uint32)NETWORK_COMMAND_GAMEINFO; #ifndef DISABLE_HTTP json_t* obj = json_object(); - json_object_set(obj, "name", json_string(gConfigNetwork.server_name)); - json_object_set(obj, "requiresPassword", json_boolean(password.size() > 0)); - json_object_set(obj, "version", json_string(OPENRCT2_VERSION)); - json_object_set(obj, "players", json_integer(player_list.size())); - json_object_set(obj, "maxPlayers", json_integer(gConfigNetwork.maxplayers)); - json_object_set(obj, "description", json_string(gConfigNetwork.server_description)); - json_object_set(obj, "dedicated", json_boolean(gOpenRCT2Headless)); + json_object_set_new(obj, "name", json_string(gConfigNetwork.server_name)); + json_object_set_new(obj, "requiresPassword", json_boolean(password.size() > 0)); + json_object_set_new(obj, "version", json_string(OPENRCT2_VERSION)); + json_object_set_new(obj, "players", json_integer(player_list.size())); + json_object_set_new(obj, "maxPlayers", json_integer(gConfigNetwork.maxplayers)); + json_object_set_new(obj, "description", json_string(gConfigNetwork.server_description)); + json_object_set_new(obj, "dedicated", json_boolean(gOpenRCT2Headless)); // Provider details json_t* jsonProvider = json_object(); - json_object_set(jsonProvider, "name", json_string(gConfigNetwork.provider_name)); - json_object_set(jsonProvider, "email", json_string(gConfigNetwork.provider_email)); - json_object_set(jsonProvider, "website", json_string(gConfigNetwork.provider_website)); - json_object_set(obj, "provider", jsonProvider); + json_object_set_new(jsonProvider, "name", json_string(gConfigNetwork.provider_name)); + json_object_set_new(jsonProvider, "email", json_string(gConfigNetwork.provider_email)); + json_object_set_new(jsonProvider, "website", json_string(gConfigNetwork.provider_website)); + json_object_set_new(obj, "provider", jsonProvider); packet->WriteString(json_dumps(obj, 0)); json_decref(obj); From 5bd3b8d6afa9b3d27bf499a52bd5da37906615b8 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Fri, 20 Nov 2015 19:41:27 +0000 Subject: [PATCH 06/14] Implement util_rand due to rand having a poor range on some platforms --- src/audio/audio.c | 2 +- src/network/network.cpp | 2 +- src/rct2.c | 3 ++- src/title.c | 10 ++++---- src/util/util.c | 18 ++++++++++++++ src/util/util.h | 3 +++ src/windows/editor_inventions_list.c | 3 ++- src/windows/guest.c | 3 ++- src/windows/mapgen.c | 5 ++-- src/windows/top_toolbar.c | 11 +++++---- src/world/balloon.c | 3 ++- src/world/climate.c | 3 ++- src/world/mapgen.c | 37 ++++++++++++++-------------- src/world/particle.c | 13 +++++----- 14 files changed, 73 insertions(+), 43 deletions(-) diff --git a/src/audio/audio.c b/src/audio/audio.c index 02f67c061e..a70b6da527 100644 --- a/src/audio/audio.c +++ b/src/audio/audio.c @@ -177,7 +177,7 @@ void start_title_music() musicPathId = PATH_ID_CSS17; break; case 3: - if (rand() & 1) + if (util_rand() & 1) musicPathId = PATH_ID_CSS50; else musicPathId = PATH_ID_CSS17; diff --git a/src/network/network.cpp b/src/network/network.cpp index d4f2e2923a..0d67273cd1 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -832,7 +832,7 @@ std::string Network::GenerateAdvertiseKey() static char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; char key[17]; for (int i = 0; i < 16; i++) { - int hexCharIndex = rand() % countof(hexChars); + int hexCharIndex = util_rand() % countof(hexChars); key[i] = hexChars[hexCharIndex]; } key[countof(key) - 1] = 0; diff --git a/src/rct2.c b/src/rct2.c index 560db3ab9a..571a7e696a 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -47,6 +47,7 @@ #include "ride/track.h" #include "scenario.h" #include "title.h" +#include "util/util.h" #include "world/map.h" #include "world/park.h" #include "world/climate.h" @@ -79,7 +80,7 @@ int rct2_init() RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, uint32) = 0; RCT2_GLOBAL(0x009AC310, char*) = RCT2_GLOBAL(RCT2_ADDRESS_CMDLINE, char*); get_system_time(); - srand((unsigned int)time(0)); + util_srand((unsigned int)time(0)); RCT2_GLOBAL(0x009DEA69, short) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_DAY, short); RCT2_GLOBAL(0x009DEA6B, short) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_MONTH, short); if (!rct2_init_directories()) diff --git a/src/title.c b/src/title.c index 1b8abc325a..0bd9c0c6d9 100644 --- a/src/title.c +++ b/src/title.c @@ -524,24 +524,24 @@ static uint8 *generate_random_script() int i, j; const int views = 16; - srand((unsigned int)time(NULL)); + util_srand((unsigned int)time(NULL)); uint8 *script = malloc(views * 8 + 2); i = 0; script[i++] = TITLE_SCRIPT_LOAD; for (j = 0; j < views; j++) { script[i++] = TITLE_SCRIPT_LOCATION; - script[i++] = 64 + (rand() % 128); - script[i++] = 64 + (rand() % 128); + script[i++] = 64 + (util_rand() % 128); + script[i++] = 64 + (util_rand() % 128); - int rotationCount = rand() % 4; + int rotationCount = util_rand() % 4; if (rotationCount > 0) { script[i++] = TITLE_SCRIPT_ROTATE; script[i++] = rotationCount; } script[i++] = TITLE_SCRIPT_WAIT; - script[i++] = 8 + (rand() % 6); + script[i++] = 8 + (util_rand() % 6); } script[i] = TITLE_SCRIPT_RESTART; diff --git a/src/util/util.c b/src/util/util.c index bfccdfa706..890423e0fd 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -220,3 +220,21 @@ bool str_is_null_or_empty(const char *str) { return str == NULL || str[0] == 0; } + +uint32 srand0, srand1, srand2, srand3; + +void util_srand(int source) { + srand0 = source; + srand1 = srand0 ^ (source >> 24); + srand2 = srand1 ^ (source >> 16); + srand3 = srand2 ^ (source >> 8); +} + +uint32 util_rand() { + uint32 temp = srand0 ^ (srand0 << 11); + srand0 = srand1; + srand1 = srand2; + srand2 = srand3; + srand3 = srand3 ^ (srand3 >> 19) ^ temp ^ (temp >> 8); + return srand3; +} \ No newline at end of file diff --git a/src/util/util.h b/src/util/util.h index 8eba3a2b3f..23ea66c2d2 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -44,4 +44,7 @@ char *safe_strncpy(char * destination, const char * source, size_t num); bool utf8_is_bom(const char *str); bool str_is_null_or_empty(const char *str); +void util_srand(int source); +uint32 util_rand(); + #endif diff --git a/src/windows/editor_inventions_list.c b/src/windows/editor_inventions_list.c index c88b5ae741..a8396b77d1 100644 --- a/src/windows/editor_inventions_list.c +++ b/src/windows/editor_inventions_list.c @@ -29,6 +29,7 @@ #include "../world/scenery.h" #include "../interface/themes.h" #include "../rct1.h" +#include "../util/util.h" #pragma region Widgets @@ -344,7 +345,7 @@ static void research_items_shuffle() // Shuffle list for (i = 0; i < numNonResearchedItems; i++) { - ri = rand() % numNonResearchedItems; + ri = util_rand() % numNonResearchedItems; if (ri == i) continue; diff --git a/src/windows/guest.c b/src/windows/guest.c index 3c5870e649..2a9eb29bdd 100644 --- a/src/windows/guest.c +++ b/src/windows/guest.c @@ -35,6 +35,7 @@ #include "../interface/viewport.h" #include "../interface/widget.h" #include "../interface/window.h" +#include "../util/util.h" #include "../world/footpath.h" #include "../world/map.h" #include "../world/sprite.h" @@ -1089,7 +1090,7 @@ void window_guest_overview_update(rct_window* w){ // Create the "I have the strangest feeling I am being watched thought" if ((w->var_494 & 0xFFFF) >= 3840) { if (!(w->var_494 & 0x3FF)) { - int random = rand() & 0xFFFF; + int random = util_rand() & 0xFFFF; if (random <= 0x2AAA) { rct_peep* peep = GET_PEEP(w->number); peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_WATCHED, 0xFF); diff --git a/src/windows/mapgen.c b/src/windows/mapgen.c index 2c46c69e47..03cb6a5e18 100644 --- a/src/windows/mapgen.c +++ b/src/windows/mapgen.c @@ -25,6 +25,7 @@ #include "../interface/viewport.h" #include "../interface/window.h" #include "../sprites.h" +#include "../util/util.h" #include "../world/mapgen.h" #include "../world/scenery.h" #include "dropdown.h" @@ -716,8 +717,8 @@ static void window_mapgen_random_mouseup(rct_window *w, int widgetIndex) mapgenSettings.wall = _randomTerrrain ? -1 : _wallTexture; mapgenSettings.trees = _placeTrees; - mapgenSettings.simplex_low = rand() % 4; - mapgenSettings.simplex_high = 12 + (rand() % (32 - 12)); + mapgenSettings.simplex_low = util_rand() % 4; + mapgenSettings.simplex_high = 12 + (util_rand() % (32 - 12)); mapgenSettings.simplex_base_freq = 1.75f; mapgenSettings.simplex_octaves = 6; diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c index 0d8f55b6da..ec8aa31f61 100644 --- a/src/windows/top_toolbar.c +++ b/src/windows/top_toolbar.c @@ -34,6 +34,7 @@ #include "../network/network.h" #include "../network/twitch.h" #include "../scenario.h" +#include "../util/util.h" #include "../world/scenery.h" #include "../world/banner.h" #include "dropdown.h" @@ -1116,7 +1117,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin uint8 rotation = window_scenery_rotation; if (!(scenery->small_scenery.flags & SMALL_SCENERY_FLAG4)){ - rotation = rand() & 0xFF; + rotation = util_rand() & 0xFF; } rotation -= get_current_rotation(); @@ -1194,7 +1195,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin uint8 rotation = window_scenery_rotation; if (!(scenery->small_scenery.flags & SMALL_SCENERY_FLAG4)){ - rotation = rand() & 0xFF; + rotation = util_rand() & 0xFF; } rotation -= get_current_rotation(); @@ -1440,11 +1441,11 @@ static void window_top_toolbar_scenery_tool_down(short x, short y, rct_window *w if (window_scenery_is_build_cluster_tool_on){ if (!(scenery->small_scenery.flags & SMALL_SCENERY_FLAG_FULL_TILE)){ parameter_2 &= 0xFF00; - parameter_2 |= rand() & 3; + parameter_2 |= util_rand() & 3; } - cur_grid_x += ((rand() % 16) - 8) * 32; - cur_grid_y += ((rand() % 16) - 8) * 32; + cur_grid_x += ((util_rand() % 16) - 8) * 32; + cur_grid_y += ((util_rand() % 16) - 8) * 32; if (!(scenery->small_scenery.flags & SMALL_SCENERY_FLAG4)){ RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_ROTATION, uint16)++; diff --git a/src/world/balloon.c b/src/world/balloon.c index 62de010dfe..6db5b5a0a0 100644 --- a/src/world/balloon.c +++ b/src/world/balloon.c @@ -1,5 +1,6 @@ #include "../audio/audio.h" #include "../scenario.h" +#include "../util/util.h" #include "sprite.h" /** @@ -68,7 +69,7 @@ void balloon_press(rct_balloon *balloon) if (balloon->popped == 1) return; - uint32 random = rand(); + uint32 random = util_rand(); if ((balloon->var_0A & 7) || (random & 0xFFFF) < 0x2000) { balloon_pop(balloon); return; diff --git a/src/world/climate.c b/src/world/climate.c index 5692acb13b..5448e8b27f 100644 --- a/src/world/climate.c +++ b/src/world/climate.c @@ -27,6 +27,7 @@ #include "../localisation/date.h" #include "../scenario.h" #include "../interface/window.h" +#include "../util/util.h" #include "climate.h" enum { @@ -115,7 +116,7 @@ void climate_reset(int climate) _rainVolume = 1; } - climate_determine_future_weather(rand()); + climate_determine_future_weather(util_rand()); } sint8 step_weather_level(sint8 cur_weather_level, sint8 next_weather_level) { diff --git a/src/world/mapgen.c b/src/world/mapgen.c index 6d89306220..4650b4307e 100644 --- a/src/world/mapgen.c +++ b/src/world/mapgen.c @@ -21,6 +21,7 @@ #include #include "../addresses.h" #include "../object.h" +#include "../util/util.h" #include "map.h" #include "map_helpers.h" #include "mapgen.h" @@ -126,7 +127,7 @@ void mapgen_generate(mapgen_settings *settings) int x, y, mapSize, floorTexture, wallTexture, waterLevel; rct_map_element *mapElement; - srand((unsigned int)time(NULL)); + util_srand((unsigned int)time(NULL)); mapSize = settings->mapSize; floorTexture = settings->floor; @@ -134,7 +135,7 @@ void mapgen_generate(mapgen_settings *settings) waterLevel = settings->waterLevel; if (floorTexture == -1) - floorTexture = BaseTerrain[rand() % countof(BaseTerrain)]; + floorTexture = BaseTerrain[util_rand() % countof(BaseTerrain)]; if (wallTexture == -1) { // Base edge type on surface type @@ -172,7 +173,7 @@ void mapgen_generate(mapgen_settings *settings) if (1) { mapgen_simplex(settings); - mapgen_smooth_height(2 + (rand() % 6)); + mapgen_smooth_height(2 + (util_rand() % 6)); } else { // Keep overwriting the map with rough cicular blobs of different sizes and heights. // This procedural method can produce intersecting contour like land and lakes. @@ -200,7 +201,7 @@ void mapgen_generate(mapgen_settings *settings) // Add sandy beaches int beachTexture = floorTexture; if (settings->floor == -1 && floorTexture == TERRAIN_GRASS) { - switch (rand() % 4) { + switch (util_rand() % 4) { case 0: beachTexture = TERRAIN_SAND; break; @@ -235,7 +236,7 @@ static void mapgen_place_tree(int type, int x, int y) mapElement = map_element_insert(x, y, surfaceZ, (1 | 2 | 4 | 8)); mapElement->clearance_height = surfaceZ + (sceneryEntry->small_scenery.height >> 3); - mapElement->type = MAP_ELEMENT_TYPE_SCENERY | (rand() % 3); + mapElement->type = MAP_ELEMENT_TYPE_SCENERY | (util_rand() % 3); mapElement->properties.scenery.type = type; mapElement->properties.scenery.age = 0; mapElement->properties.scenery.colour_1 = 26; @@ -310,7 +311,7 @@ static void mapgen_place_trees() // Shuffle list for (i = 0; i < availablePositionsCount; i++) { - rindex = rand() % availablePositionsCount; + rindex = util_rand() % availablePositionsCount; if (rindex == i) continue; @@ -320,7 +321,7 @@ static void mapgen_place_trees() } // Place trees - float treeToLandRatio = (10 + (rand() % 30)) / 100.0f; + float treeToLandRatio = (10 + (util_rand() % 30)) / 100.0f; int numTrees = max(4, (int)(availablePositionsCount * treeToLandRatio)); mapSize = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, sint16); @@ -336,7 +337,7 @@ static void mapgen_place_trees() if (numGrassTreeIds == 0) break; - type = grassTreeIds[rand() % numGrassTreeIds]; + type = grassTreeIds[util_rand() % numGrassTreeIds]; break; case TERRAIN_SAND: @@ -345,15 +346,15 @@ static void mapgen_place_trees() if (numDesertTreeIds == 0) break; - if (rand() % 4 == 0) - type = desertTreeIds[rand() % numDesertTreeIds]; + if (util_rand() % 4 == 0) + type = desertTreeIds[util_rand() % numDesertTreeIds]; break; case TERRAIN_ICE: if (numSnowTreeIds == 0) break; - type = snowTreeIds[rand() % numSnowTreeIds]; + type = snowTreeIds[util_rand() % numSnowTreeIds]; break; } @@ -392,15 +393,15 @@ static void mapgen_blobs(int count, int lowSize, int highSize, int lowHeight, in int sizeRange = highSize - lowSize; int heightRange = highHeight - lowHeight; - int border = 2 + (rand() % 24); + int border = 2 + (util_rand() % 24); int borderRange = _heightSize - (border * 2); for (i = 0; i < count; i++) { - int radius = lowSize + (rand() % sizeRange); + int radius = lowSize + (util_rand() % sizeRange); mapgen_blob( - border + (rand() % borderRange), - border + (rand() % borderRange), + border + (util_rand() % borderRange), + border + (util_rand() % borderRange), (int)(M_PI * radius * radius), - lowHeight + (rand() % heightRange) + lowHeight + (util_rand() % heightRange) ); } } @@ -506,7 +507,7 @@ static void mapgen_blob(int cx, int cy, int size, int height) set_height(x, y, BLOB_HEIGHT); while (currentSize < size) { - if (rand() % 2 == 0) { + if (util_rand() % 2 == 0) { set_height(x, y, BLOB_HEIGHT); currentSize++; } @@ -655,7 +656,7 @@ static uint8 perm[512]; static void noise_rand() { for (int i = 0; i < countof(perm); i++) - perm[i] = rand() & 0xFF; + perm[i] = util_rand() & 0xFF; } static float fractal_noise(int x, int y, float frequency, int octaves, float lacunarity, float persistence) diff --git a/src/world/particle.c b/src/world/particle.c index 1636b3ac42..0b754193cd 100644 --- a/src/world/particle.c +++ b/src/world/particle.c @@ -1,4 +1,5 @@ #include "../audio/audio.h" +#include "../util/util.h" #include "sprite.h" /** @@ -18,12 +19,12 @@ void crashed_vehicle_particle_create(rct_vehicle_colour colours, int x, int y, i sprite_move(x, y, z + 4, (rct_sprite*)sprite); sprite->misc_identifier = SPRITE_MISC_CRASHED_VEHICLE_PARTICLE; - sprite->var_26 = (rand() & 0xFF) * 12; - sprite->var_24 = (rand() & 0x7F) + 140; - sprite->var_2E = ((rand() & 0xFF) * 5) >> 8; - sprite->acceleration_x = (rand() & 0xFFFF) * 4; - sprite->acceleration_y = (rand() & 0xFFFF) * 4; - sprite->acceleration_z = (rand() & 0xFFFF) * 4 + 0x10000; + sprite->var_26 = (util_rand() & 0xFF) * 12; + sprite->var_24 = (util_rand() & 0x7F) + 140; + sprite->var_2E = ((util_rand() & 0xFF) * 5) >> 8; + sprite->acceleration_x = (util_rand() & 0xFFFF) * 4; + sprite->acceleration_y = (util_rand() & 0xFFFF) * 4; + sprite->acceleration_z = (util_rand() & 0xFFFF) * 4 + 0x10000; sprite->velocity_x = 0; sprite->velocity_y = 0; sprite->velocity_z = 0; From 5a9a372100a83ac5f1c25184921d1279d654701e Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Fri, 20 Nov 2015 19:54:43 +0000 Subject: [PATCH 07/14] change branch name - this should have been done when branch was created :/ --- src/rct2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rct2.h b/src/rct2.h index 841aa697d8..5e3ce17ceb 100644 --- a/src/rct2.h +++ b/src/rct2.h @@ -102,7 +102,7 @@ typedef utf16* utf16string; // The following constants are for automated build servers #define OPENRCT2_BUILD_NUMBER "" #define OPENRCT2_BUILD_SERVER "" -#define OPENRCT2_BRANCH "develop" +#define OPENRCT2_BRANCH "pre-release-0.0.3" #define OPENRCT2_COMMIT_SHA1 "" #define OPENRCT2_COMMIT_SHA1_SHORT "" #define OPENRCT2_MASTER_SERVER_URL "https://servers.openrct2.website" From cba189c2de20899bfc37abe7fd575b9bf4a06ee8 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 23 Nov 2015 18:25:43 +0000 Subject: [PATCH 08/14] Fix #2326. Fixed research bugging out when going back to object selection --- src/management/research.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/management/research.c b/src/management/research.c index 5873493565..83df0fd6a1 100644 --- a/src/management/research.c +++ b/src/management/research.c @@ -417,6 +417,12 @@ static void research_insert_researched(int entryIndex, int category) { rct_research_item *researchItem, *researchItem2; + researchItem = gResearchItems; + // First check to make sure that entry is not already accounted for + for (; researchItem->entryIndex != RESEARCHED_ITEMS_END; researchItem++) { + if (researchItem->entryIndex == entryIndex) + return; + } researchItem = gResearchItems; do { if (researchItem->entryIndex == RESEARCHED_ITEMS_SEPARATOR) { From 83d183954a27af106d01dcbc4c903c89c2b90ee9 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 24 Nov 2015 20:10:03 +0000 Subject: [PATCH 09/14] Fix #2337. Fixed footpath placements with walls. --- src/world/footpath.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/world/footpath.c b/src/world/footpath.c index adc78bdde1..dcaaa23102 100644 --- a/src/world/footpath.c +++ b/src/world/footpath.c @@ -890,7 +890,12 @@ static void footpath_connect_corners(int initialX, int initialY, rct_map_element direction = (direction + 1) & 3; x += TileDirectionDelta[direction].x; y += TileDirectionDelta[direction].y; - mapElement[3] = footpath_connect_corners_get_neighbour(x, y, z, (1 << (direction ^ 2)) | (1 << (((direction ^ 2) - 1) & 3))); + // First check link to previous tile + mapElement[3] = footpath_connect_corners_get_neighbour(x, y, z, (1 << (direction ^ 2))); + if (mapElement[3] == NULL) + continue; + // Second check link to initial tile + mapElement[3] = footpath_connect_corners_get_neighbour(x, y, z, (1 << ((direction + 1) & 3))); if (mapElement[3] == NULL) continue; @@ -906,7 +911,7 @@ static void footpath_connect_corners(int initialX, int initialY, rct_map_element mapElement[1]->properties.path.edges |= (1 << (direction + 4)); map_invalidate_element(x, y, mapElement[1]); - direction = (direction - 1) & 3; + direction = initialDirection; mapElement[0]->properties.path.edges |= (1 << (direction + 4)); map_invalidate_element(x, y, mapElement[0]); } From 99a91b11c52c2459d16e33b4fae63f27eabaae9c Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Thu, 26 Nov 2015 16:36:36 +0100 Subject: [PATCH 10/14] UK: Fahrenheit degree symbol --- data/language/english_uk.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/language/english_uk.txt b/data/language/english_uk.txt index fc5773a30c..95b9afb293 100644 --- a/data/language/english_uk.txt +++ b/data/language/english_uk.txt @@ -2221,7 +2221,7 @@ STR_2213 :{SMALLFONT}{BLACK}Show list of entertainers in park STR_2214 :Construction not possible while game is paused! STR_2215 :{STRINGID}{NEWLINE}({STRINGID}) STR_2216 :{WINDOW_COLOUR_2}{COMMA16}{DEGREE}C -STR_2217 :{WINDOW_COLOUR_2}{COMMA16}F +STR_2217 :{WINDOW_COLOUR_2}{COMMA16}{DEGREE}F STR_2218 :{RED}{STRINGID} on {STRINGID} hasn't returned to the {STRINGID} yet!{NEWLINE}Check whether it is stuck or has stalled STR_2219 :{RED}{COMMA16} people have died in an accident on {STRINGID} STR_2220 :{WINDOW_COLOUR_2}Park Rating: {BLACK}{COMMA16} From ceeedc50cdaa3a843f7a7bba4b09e3640f97149a Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Thu, 26 Nov 2015 23:38:24 +0100 Subject: [PATCH 11/14] UK: Missed occurrence of the Fahrenreit symbol Thanks to @e-foley for pointing it out. --- data/language/english_uk.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/language/english_uk.txt b/data/language/english_uk.txt index 95b9afb293..5e04bf96fe 100644 --- a/data/language/english_uk.txt +++ b/data/language/english_uk.txt @@ -2371,7 +2371,7 @@ STR_2363 :Gridlines on Landscape STR_2364 :{SMALLFONT}{BLACK}Toggle gridlines on landscape on/off STR_2365 :The bank refuses to increase your loan! STR_2366 :Celsius ({DEGREE}C) -STR_2367 :Fahrenheit (F) +STR_2367 :Fahrenheit ({DEGREE}F) STR_2368 :None STR_2369 :Low STR_2370 :Average From 119ca58cc740f296e2cf7b5624a27109be2ee135 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Fri, 27 Nov 2015 18:01:45 +0000 Subject: [PATCH 12/14] Add check to prevent exceeding the maximum number of animations. Probable cause of #2381 --- src/world/map_animation.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/world/map_animation.c b/src/world/map_animation.c index 0ce1832451..18cb07daf0 100644 --- a/src/world/map_animation.c +++ b/src/world/map_animation.c @@ -49,6 +49,10 @@ void map_animation_create(int type, int x, int y, int z) { rct_map_animation *aobj = &gAnimatedObjects[0]; int numAnimatedObjects = RCT2_GLOBAL(0x0138B580, uint16); + if (numAnimatedObjects >= 2000) { + log_error("Exceeded the maximum number of animations"); + return; + } for (int i = 0; i < numAnimatedObjects; i++, aobj++) { if (aobj->x != x) continue; From 691aec5035f7f39634b0a16e93ab19f1a2d14522 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Fri, 27 Nov 2015 18:40:37 +0000 Subject: [PATCH 13/14] Fix #2381. Map animation invalidate now called during pause mode This was causing the number of map animations to skyrocket as there was no way to remove animations caused by ghosts. This shouldn't progress the animation only remove invalid animations. --- src/game.c | 3 +++ src/world/map_animation.c | 13 +++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/game.c b/src/game.c index 10c4c61466..9b872c6a47 100644 --- a/src/game.c +++ b/src/game.c @@ -269,6 +269,9 @@ void game_update() } else { if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) != 0) { numUpdates = 0; + // Update the animation list. Note this does not + // increment the map animation. + map_animation_invalidate_all(); } } diff --git a/src/world/map_animation.c b/src/world/map_animation.c index 18cb07daf0..ab45491527 100644 --- a/src/world/map_animation.c +++ b/src/world/map_animation.c @@ -194,7 +194,7 @@ static bool map_animation_invalidate_small_scenery(int x, int y, int baseZ) if (sceneryEntry->small_scenery.flags & SMALL_SCENERY_FLAG_IS_CLOCK) { // Peep, looking at scenery - if (!(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 0x3FF)) { + if (!(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 0x3FF) && RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) == 0) { int direction = mapElement->type & 3; int x2 = x - TileDirectionDelta[direction].x; int y2 = y - TileDirectionDelta[direction].y; @@ -324,6 +324,9 @@ static bool map_animation_invalidate_track_onridephoto(int x, int y, int baseZ) if (mapElement->properties.track.type == TRACK_ELEM_ON_RIDE_PHOTO) { int z = mapElement->base_height * 8; map_invalidate_tile_zoom1(x, y, mapElement->base_height * 8, mapElement->clearance_height * 8); + if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) != 0) { + return false; + } if (mapElement->properties.track.sequence & 0xF0) { mapElement->properties.track.sequence -= 0x10; return false; @@ -450,7 +453,7 @@ static bool map_animation_invalidate_large_scenery(int x, int y, int baseZ) * * rct2: 0x006E5B50 */ -static bool map_animation_invalidate_wall_unknown(int x, int y, int baseZ) +static bool map_animation_invalidate_wall_door(int x, int y, int baseZ) { rct_map_element *mapElement; rct_scenery_entry *sceneryEntry; @@ -489,7 +492,9 @@ static bool map_animation_invalidate_wall_unknown(int x, int y, int baseZ) } } } - + if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) != 0) { + return false; + } mapElement->properties.fence.item[2] = bl; if (di & 1) { int z = mapElement->base_height * 8; @@ -545,6 +550,6 @@ static const map_animation_invalidate_event_handler _animatedObjectEventHandlers map_animation_invalidate_remove, map_animation_invalidate_banner, map_animation_invalidate_large_scenery, - map_animation_invalidate_wall_unknown, + map_animation_invalidate_wall_door, map_animation_invalidate_wall }; From 843999997b4d3d5e28cc68350780f92545887864 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Fri, 27 Nov 2015 19:17:35 +0000 Subject: [PATCH 14/14] Fix #2375. Issue caused by invalid z coordinate for invalidate. Also fixed a couple other functions which were calling with the incorrect z value --- src/world/footpath.c | 5 +++-- src/world/map.c | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/world/footpath.c b/src/world/footpath.c index dcaaa23102..ee57d5e0b4 100644 --- a/src/world/footpath.c +++ b/src/world/footpath.c @@ -1347,6 +1347,7 @@ void footpath_chain_ride_queue(int rideIndex, int entranceIndex, int x, int y, r mapElement->properties.path.ride_index = rideIndex; mapElement->properties.path.additions &= 0x8F; mapElement->properties.path.additions |= (entranceIndex & 7) << 4; + if (lastQueuePathElement == NULL) { lastQueuePathElement = mapElement; } @@ -1842,7 +1843,7 @@ static void footpath_remove_edges_towards_here(int x, int y, int z, int directio mapElement->properties.path.edges &= ~(1 << d); d = (((d - 4) + 1) & 3) + 4; mapElement->properties.path.edges &= ~(1 << d); - map_invalidate_tile(x, y, mapElement->base_height, mapElement->clearance_height); + map_invalidate_tile(x, y, mapElement->base_height * 8, mapElement->clearance_height * 8); if (isQueue) footpath_disconnect_queue_from_path(x, y, mapElement, -1); @@ -1862,7 +1863,7 @@ static void footpath_remove_edges_towards_here(int x, int y, int z, int directio d = ((direction + 1) & 3) + 4; mapElement->properties.path.edges &= ~(1 << d); - map_invalidate_tile(x, y, mapElement->base_height, mapElement->clearance_height); + map_invalidate_tile(x, y, mapElement->base_height * 8, mapElement->clearance_height * 8); break; } while (!map_element_is_last_for_tile(mapElement++)); } diff --git a/src/world/map.c b/src/world/map.c index 8f4f588a45..e86aaf5483 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -4263,7 +4263,7 @@ repeat: continue; map_element_remove_banner_entry(mapElement); - map_invalidate_tile_zoom1(x, y, mapElement->base_height, mapElement->base_height + 72); + map_invalidate_tile_zoom1(x, y, mapElement->base_height * 8, mapElement->base_height * 8 + 72); map_element_remove(mapElement); goto repeat; } while (!map_element_is_last_for_tile(mapElement++)); @@ -4367,7 +4367,7 @@ void map_invalidate_tile_full(int x, int y) void map_invalidate_element(int x, int y, rct_map_element *mapElement) { - map_invalidate_tile(x, y, mapElement->base_height, mapElement->clearance_height); + map_invalidate_tile(x, y, mapElement->base_height * 8, mapElement->clearance_height * 8); } int map_get_tile_side(int mapX, int mapY) @@ -4510,7 +4510,7 @@ money32 place_park_entrance(int flags, sint16 x, sint16 y, sint16 z, uint8 direc update_park_fences(x, y - 32); update_park_fences(x, y + 32); - map_invalidate_tile(x, y, newElement->base_height, newElement->clearance_height); + map_invalidate_tile(x, y, newElement->base_height * 8, newElement->clearance_height * 8); map_animation_create(MAP_ANIMATION_TYPE_PARK_ENTRANCE, x, y, zLow); } @@ -4547,7 +4547,7 @@ money32 place_park_entrance(int flags, sint16 x, sint16 y, sint16 z, uint8 direc update_park_fences(x, y - 32); update_park_fences(x, y + 32); - map_invalidate_tile(x, y, newElement->base_height, newElement->clearance_height); + map_invalidate_tile(x, y, newElement->base_height * 8, newElement->clearance_height * 8); } x += TileDirectionDelta[(direction + 1) & 0x3].x * 2; @@ -4582,7 +4582,7 @@ money32 place_park_entrance(int flags, sint16 x, sint16 y, sint16 z, uint8 direc update_park_fences(x, y - 32); update_park_fences(x, y + 32); - map_invalidate_tile(x, y, newElement->base_height, newElement->clearance_height); + map_invalidate_tile(x, y, newElement->base_height * 8, newElement->clearance_height * 8); } return 0;