Tour localSearch_randomBestPath(Instance pInstance, int pTryNb) { Tour ret, buffTour; int first2opt, second2opt; int i; buffTour = tour_randomWalk(pInstance); ret = buffTour; if(gVerboseMode) { printf("Random walk:\n "); tour_display(buffTour); printf("\n\n"); } for(i=0 ; i < pTryNb ; ++i) { do { first2opt = util_rand(1, pInstance.nbTowns); second2opt = util_rand(1, pInstance.nbTowns); } while(first2opt == second2opt || (first2opt == second2opt-1 || second2opt == first2opt-1)); tour_2opt(&buffTour, first2opt, second2opt); if(buffTour.length < ret.length) { ret = buffTour; if(gVerboseMode) { printf("\nMeilleur tour après 2opt numéro %d: \n", i+1); tour_display(ret); printf("\n"); } } } return ret; }
/** * * rct2: 0x00685A93 */ void research_items_shuffle() { rct_research_item *researchItem, *researchOrderBase, researchItemTemp; int32_t i, numNonResearchedItems; // Skip pre-researched items for (researchItem = gResearchItems; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) { } researchItem++; researchOrderBase = researchItem; // Count non pre-researched items numNonResearchedItems = 0; for (; researchItem->rawValue != RESEARCHED_ITEMS_END; researchItem++) numNonResearchedItems++; // Shuffle list for (i = 0; i < numNonResearchedItems; i++) { int32_t ri = util_rand() % numNonResearchedItems; if (ri == i) continue; researchItemTemp = researchOrderBase[i]; researchOrderBase[i] = researchOrderBase[ri]; researchOrderBase[ri] = researchItemTemp; } }
static void mapgen_blobs(sint32 count, sint32 lowSize, sint32 highSize, sint32 lowHeight, sint32 highHeight) { sint32 i; sint32 sizeRange = highSize - lowSize; sint32 heightRange = highHeight - lowHeight; sint32 border = 2 + (util_rand() % 24); sint32 borderRange = _heightSize - (border * 2); for (i = 0; i < count; i++) { sint32 radius = lowSize + (util_rand() % sizeRange); mapgen_blob( border + (util_rand() % borderRange), border + (util_rand() % borderRange), (sint32)(M_PI * radius * radius), lowHeight + (util_rand() % heightRange) ); } }
static void mapgen_blobs(int count, int lowSize, int highSize, int lowHeight, int highHeight) { int i; int sizeRange = highSize - lowSize; int heightRange = highHeight - lowHeight; int border = 2 + (util_rand() % 24); int borderRange = _heightSize - (border * 2); for (i = 0; i < count; i++) { int radius = lowSize + (util_rand() % sizeRange); mapgen_blob( border + (util_rand() % borderRange), border + (util_rand() % borderRange), (int)(M_PI * radius * radius), lowHeight + (util_rand() % heightRange) ); } }
static void window_mapgen_random_mouseup(rct_window *w, int widgetIndex) { mapgen_settings mapgenSettings; switch (widgetIndex) { case WIDX_CLOSE: window_close(w); break; case WIDX_TAB_1: case WIDX_TAB_2: case WIDX_TAB_3: window_mapgen_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_GENERATE: mapgenSettings.mapSize = _mapSize; mapgenSettings.height = _baseHeight + 2; mapgenSettings.waterLevel = _waterLevel + 2; mapgenSettings.floor = _randomTerrrain ? -1 : _floorTexture; mapgenSettings.wall = _randomTerrrain ? -1 : _wallTexture; mapgenSettings.trees = _placeTrees; mapgenSettings.simplex_low = util_rand() % 4; mapgenSettings.simplex_high = 12 + (util_rand() % (32 - 12)); mapgenSettings.simplex_base_freq = 1.75f; mapgenSettings.simplex_octaves = 6; mapgen_generate(&mapgenSettings); gfx_invalidate_screen(); break; case WIDX_RANDOM_TERRAIN: _randomTerrrain ^= 1; break; case WIDX_PLACE_TREES: _placeTrees ^= 1; break; } }
static void mapgen_place_tree(sint32 type, sint32 x, sint32 y) { sint32 surfaceZ; rct_map_element *mapElement; rct_scenery_entry *sceneryEntry = get_small_scenery_entry(type); surfaceZ = map_element_height(x * 32 + 16, y * 32 + 16) / 8; mapElement = map_element_insert(x, y, surfaceZ, (1 | 2 | 4 | 8)); assert(mapElement != NULL); mapElement->clearance_height = surfaceZ + (sceneryEntry->small_scenery.height >> 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 = COLOUR_YELLOW; }
static void mapgen_place_tree(int type, int x, int y) { int surfaceZ; rct_map_element *mapElement; rct_scenery_entry *sceneryEntry = g_smallSceneryEntries[type]; surfaceZ = map_element_height(x * 32 + 16, y * 32 + 16) / 8; 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 | (util_rand() % 3); mapElement->properties.scenery.type = type; mapElement->properties.scenery.age = 0; mapElement->properties.scenery.colour_1 = 26; mapElement->properties.scenery.colour_1 = 18; }
static void noise_rand() { for (sint32 i = 0; i < countof(perm); i++) perm[i] = util_rand() & 0xFF; }
/** * Sets a rough circular blob of tiles of the specified size to the specified height. */ static void mapgen_blob(sint32 cx, sint32 cy, sint32 size, sint32 height) { sint32 x, y, currentSize, direction; x = cx; y = cy; currentSize = 1; direction = 0; set_height(x, y, BLOB_HEIGHT); while (currentSize < size) { if (util_rand() % 2 == 0) { set_height(x, y, BLOB_HEIGHT); currentSize++; } switch (direction) { case 0: if (y == 0) { currentSize = size; break; } y--; if (get_height(x + 1, y) != BLOB_HEIGHT) direction = 1; else if (get_height(x, y - 1) != BLOB_HEIGHT) direction = 0; else if (get_height(x - 1, y) != BLOB_HEIGHT) direction = 3; break; case 1: if (x == _heightSize - 1) { currentSize = size; break; } x++; if (get_height(x, y + 1) != BLOB_HEIGHT) direction = 2; else if (get_height(x + 1, y) != BLOB_HEIGHT) direction = 1; else if (get_height(x, y - 1) != BLOB_HEIGHT) direction = 0; break; case 2: if (y == _heightSize - 1) { currentSize = size; break; } y++; if (get_height(x - 1, y) != BLOB_HEIGHT) direction = 3; else if (get_height(x, y + 1) != BLOB_HEIGHT) direction = 2; else if (get_height(x + 1, y) != BLOB_HEIGHT) direction = 1; break; case 3: if (x == 0) { currentSize = size; break; } x--; if (get_height(x, y - 1) != BLOB_HEIGHT) direction = 0; else if (get_height(x - 1, y) != BLOB_HEIGHT) direction = 3; else if (get_height(x, y + 1) != BLOB_HEIGHT) direction = 2; break; } } mapgen_blob_fill(height); }
/** * Randomly places a selection of preset trees on the map. Picks the right tree for the terrain it is placing it on. */ static void mapgen_place_trees() { sint32 numGrassTreeIds = 0, numDesertTreeIds = 0, numSnowTreeIds = 0; sint32 *grassTreeIds = (sint32*)malloc(countof(GrassTrees) * sizeof(sint32)); sint32 *desertTreeIds = (sint32*)malloc(countof(DesertTrees) * sizeof(sint32)); sint32 *snowTreeIds = (sint32*)malloc(countof(SnowTrees) * sizeof(sint32)); for (sint32 i = 0; i < object_entry_group_counts[OBJECT_TYPE_SMALL_SCENERY]; i++) { rct_scenery_entry *sceneryEntry = get_small_scenery_entry(i); rct_object_entry_extended *entry = &object_entry_groups[OBJECT_TYPE_SMALL_SCENERY].entries[i]; if (sceneryEntry == (rct_scenery_entry*)-1 || sceneryEntry == NULL) continue; sint32 j; for (j = 0; j < countof(GrassTrees); j++) if (strncmp(GrassTrees[j], entry->name, 8) == 0) break; if (j != countof(GrassTrees)) { grassTreeIds[numGrassTreeIds++] = i; continue; } for (j = 0; j < countof(DesertTrees); j++) if (strncmp(DesertTrees[j], entry->name, 8) == 0) break; if (j != countof(DesertTrees)) { desertTreeIds[numDesertTreeIds++] = i; continue; } for (j = 0; j < countof(SnowTrees); j++) if (strncmp(SnowTrees[j], entry->name, 8) == 0) break; if (j != countof(SnowTrees)) { snowTreeIds[numSnowTreeIds++] = i; continue; } } sint32 availablePositionsCount = 0; struct { sint32 x; sint32 y; } tmp, *pos, *availablePositions; availablePositions = malloc(256 * 256 * sizeof(tmp)); // Create list of available tiles for (sint32 y = 1; y < gMapSize - 1; y++) { for (sint32 x = 1; x < gMapSize - 1; x++) { rct_map_element *mapElement = map_get_surface_element_at(x, y); // Exclude water tiles if ((mapElement->properties.surface.terrain & 0x1F) != 0) continue; pos = &availablePositions[availablePositionsCount++]; pos->x = x; pos->y = y; } } // Shuffle list for (sint32 i = 0; i < availablePositionsCount; i++) { sint32 rindex = util_rand() % availablePositionsCount; if (rindex == i) continue; tmp = availablePositions[i]; availablePositions[i] = availablePositions[rindex]; availablePositions[rindex] = tmp; } // Place trees float treeToLandRatio = (10 + (util_rand() % 30)) / 100.0f; sint32 numTrees = max(4, (sint32)(availablePositionsCount * treeToLandRatio)); for (sint32 i = 0; i < numTrees; i++) { pos = &availablePositions[i]; sint32 type = -1; rct_map_element *mapElement = map_get_surface_element_at(pos->x, pos->y); switch (map_element_get_terrain(mapElement)) { case TERRAIN_GRASS: case TERRAIN_DIRT: case TERRAIN_GRASS_CLUMPS: if (numGrassTreeIds == 0) break; type = grassTreeIds[util_rand() % numGrassTreeIds]; break; case TERRAIN_SAND: case TERRAIN_SAND_DARK: case TERRAIN_SAND_LIGHT: if (numDesertTreeIds == 0) break; if (util_rand() % 4 == 0) type = desertTreeIds[util_rand() % numDesertTreeIds]; break; case TERRAIN_ICE: if (numSnowTreeIds == 0) break; type = snowTreeIds[util_rand() % numSnowTreeIds]; break; } if (type != -1) mapgen_place_tree(type, pos->x, pos->y); } free(availablePositions); free(grassTreeIds); free(desertTreeIds); free(snowTreeIds); }
void mapgen_generate(mapgen_settings *settings) { sint32 x, y, mapSize, floorTexture, wallTexture, waterLevel; rct_map_element *mapElement; util_srand((sint32)SDL_GetTicks()); mapSize = settings->mapSize; floorTexture = settings->floor; wallTexture = settings->wall; waterLevel = settings->waterLevel; if (floorTexture == -1) floorTexture = BaseTerrain[util_rand() % countof(BaseTerrain)]; if (wallTexture == -1) { // Base edge type on surface type switch (floorTexture) { case TERRAIN_DIRT: wallTexture = TERRAIN_EDGE_WOOD_RED; break; case TERRAIN_ICE: wallTexture = TERRAIN_EDGE_ICE; break; default: wallTexture = TERRAIN_EDGE_ROCK; break; } } map_clear_all_elements(); // Initialise the base map map_init(mapSize); for (y = 1; y < mapSize - 1; y++) { for (x = 1; x < mapSize - 1; x++) { mapElement = map_get_surface_element_at(x, y); map_element_set_terrain(mapElement, floorTexture); map_element_set_terrain_edge(mapElement, wallTexture); mapElement->base_height = settings->height; mapElement->clearance_height = settings->height; } } // Create the temporary height map and initialise _heightSize = mapSize * 2; _height = (uint8*)malloc(_heightSize * _heightSize * sizeof(uint8)); memset(_height, 0, _heightSize * _heightSize * sizeof(uint8)); if (1) { mapgen_simplex(settings); 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. // Large blobs, general shape of map mapgen_blobs(6, _heightSize / 2, _heightSize * 4, 4, 16); // Medium blobs mapgen_blobs(12, _heightSize / 16, _heightSize / 8, 4, 18); // Small blobs, small hills and lakes mapgen_blobs(32, _heightSize / 32, _heightSize / 16, 4, 18); // Smooth the land so that their aren't cliffs round every blob. mapgen_smooth_height(2); } // Set the game map to the height map mapgen_set_height(); free(_height); // Set the tile slopes so that there are no cliffs while (map_smooth(1, 1, mapSize - 1, mapSize - 1)) { } // Add the water mapgen_set_water_level(waterLevel); // Add sandy beaches sint32 beachTexture = floorTexture; if (settings->floor == -1 && floorTexture == TERRAIN_GRASS) { switch (util_rand() % 4) { case 0: beachTexture = TERRAIN_SAND; break; case 1: beachTexture = TERRAIN_SAND_LIGHT; break; } } for (y = 1; y < mapSize - 1; y++) { for (x = 1; x < mapSize - 1; x++) { mapElement = map_get_surface_element_at(x, y); if (mapElement->base_height < waterLevel + 6) map_element_set_terrain(mapElement, beachTexture); } } // Place the trees if (settings->trees != 0) mapgen_place_trees(); map_reorganise_elements(); }
/** * Weather & climate update iteration. * Gradually changes the weather parameters towards their determined next values. */ void climate_update() { // Only do climate logic if playing (not in scenario editor or title screen) if (gScreenFlags & (~SCREEN_FLAGS_PLAYING)) return; if (!gCheatsFreezeClimate) { if (gClimateUpdateTimer) { if (gClimateUpdateTimer == 960) { auto intent = Intent(INTENT_ACTION_UPDATE_CLIMATE); context_broadcast_intent(&intent); } gClimateUpdateTimer--; } else if (!(gCurrentTicks & 0x7F)) { if (gClimateCurrent.Temperature == gClimateNext.Temperature) { if (gClimateCurrent.WeatherGloom == gClimateNext.WeatherGloom) { gClimateCurrent.WeatherEffect = gClimateNext.WeatherEffect; _thunderTimer = 0; _lightningTimer = 0; if (gClimateCurrent.RainLevel == gClimateNext.RainLevel) { gClimateCurrent.Weather = gClimateNext.Weather; climate_determine_future_weather(scenario_rand()); auto intent = Intent(INTENT_ACTION_UPDATE_CLIMATE); context_broadcast_intent(&intent); } else if (gClimateNext.RainLevel <= RAIN_LEVEL_HEAVY) { gClimateCurrent.RainLevel = climate_step_weather_level(gClimateCurrent.RainLevel, gClimateNext.RainLevel); } } else { gClimateCurrent.WeatherGloom = climate_step_weather_level(gClimateCurrent.WeatherGloom, gClimateNext.WeatherGloom); gfx_invalidate_screen(); } } else { gClimateCurrent.Temperature = climate_step_weather_level(gClimateCurrent.Temperature, gClimateNext.Temperature); auto intent = Intent(INTENT_ACTION_UPDATE_CLIMATE); context_broadcast_intent(&intent); } } } if (_thunderTimer != 0) { climate_update_lightning(); climate_update_thunder(); } else if (gClimateCurrent.WeatherEffect == WEATHER_EFFECT_STORM) { // Create new thunder and lightning uint32 randomNumber = util_rand(); if ((randomNumber & 0xFFFF) <= 0x1B4) { randomNumber >>= 16; _thunderTimer = 43 + (randomNumber % 64); _lightningTimer = randomNumber % 32; }