From 76b2e1c5ab908a38bcb3bd8e846c8fc827930c87 Mon Sep 17 00:00:00 2001 From: rubidium Date: Mon, 30 Mar 2009 23:15:05 +0000 Subject: [PATCH] (svn r15903) [0.7] -Backport from trunk: - Fix: YAPF did not apply the platform length (too long/too short) penalties (r15900) - Fix: Fixing the slopes was done a bit more often than intended making map generation with the original generator horribly slow (r15895) - Fix: YAPF used different penalties for aqueducts than for other water tiles (r15891) - Fix: Round the production rate up, so e.g. oilrigs always produce some passengers on lowest production level [FS#2772] (r15888) - Fix: Libtimidity cannot handle frees of NULL (in contrast of most other frees) [FS#2770] (r15886) - Fix: Make sure house class/ID counters do not overflow (r15831) --- src/industry_cmd.cpp | 5 +++-- src/landscape.cpp | 3 +-- src/music/libtimidity.cpp | 15 ++++++++------- src/town_cmd.cpp | 22 ++++++++++++++++------ src/yapf/yapf_common.hpp | 2 +- src/yapf/yapf_costrail.hpp | 10 +++++----- src/yapf/yapf_ship.cpp | 4 ++-- 7 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index d28b490c34..88cdf7a09a 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -2211,8 +2211,9 @@ static void ChangeIndustryProduction(Industry *i, bool monthly) /* Recalculate production_rate * For non-smooth economy these should always be synchronized with prod_level */ if (recalculate_multipliers) { - i->production_rate[0] = min(indspec->production_rate[0] * i->prod_level / PRODLEVEL_DEFAULT, 0xFF); - i->production_rate[1] = min(indspec->production_rate[1] * i->prod_level / PRODLEVEL_DEFAULT, 0xFF); + /* Rates are rounded up, so e.g. oilrig always produces some passengers */ + i->production_rate[0] = min((indspec->production_rate[0] * i->prod_level + PRODLEVEL_DEFAULT - 1) / PRODLEVEL_DEFAULT, 0xFF); + i->production_rate[1] = min((indspec->production_rate[1] * i->prod_level + PRODLEVEL_DEFAULT - 1) / PRODLEVEL_DEFAULT, 0xFF); } /* Close if needed and allowed */ diff --git a/src/landscape.cpp b/src/landscape.cpp index bd5feeaea2..e599203c55 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -815,8 +815,6 @@ static void GenerateTerrain(int type, uint flag) } while (--w != 0); break; } - - FixSlopes(); } @@ -930,6 +928,7 @@ void GenerateLandscape(byte mode) } } + FixSlopes(); ConvertGroundTilesIntoWaterTiles(); if (_settings_game.game_creation.landscape == LT_TROPIC) CreateDesertOrRainForest(); diff --git a/src/music/libtimidity.cpp b/src/music/libtimidity.cpp index fe086c24d7..eedc75d604 100644 --- a/src/music/libtimidity.cpp +++ b/src/music/libtimidity.cpp @@ -50,6 +50,7 @@ static FMusicDriver_LibTimidity iFMusicDriver_LibTimidity; const char *MusicDriver_LibTimidity::Start(const char * const *param) { _midi.status = MIDI_STOPPED; + _midi.song = NULL; if (mid_init(param == NULL ? NULL : (char *)param[0]) < 0) { /* If init fails, it can be because no configuration was found. @@ -81,15 +82,14 @@ const char *MusicDriver_LibTimidity::Start(const char * const *param) void MusicDriver_LibTimidity::Stop() { - if (_midi.status == MIDI_PLAYING) { - _midi.status = MIDI_STOPPED; - mid_song_free(_midi.song); - } + if (_midi.status == MIDI_PLAYING) this->StopSong(); mid_exit(); } void MusicDriver_LibTimidity::PlaySong(const char *filename) { + this->StopSong(); + _midi.stream = mid_istream_open_file(filename); if (_midi.stream == NULL) { DEBUG(driver, 0, "Could not open music file"); @@ -112,7 +112,9 @@ void MusicDriver_LibTimidity::PlaySong(const char *filename) void MusicDriver_LibTimidity::StopSong() { _midi.status = MIDI_STOPPED; - mid_song_free(_midi.song); + /* mid_song_free cannot handle NULL! */ + if (_midi.song != NULL) mid_song_free(_midi.song); + _midi.song = NULL; } bool MusicDriver_LibTimidity::IsSongPlaying() @@ -130,6 +132,5 @@ bool MusicDriver_LibTimidity::IsSongPlaying() void MusicDriver_LibTimidity::SetVolume(byte vol) { - if (_midi.song != NULL) - mid_song_set_volume(_midi.song, vol); + if (_midi.song != NULL) mid_song_set_volume(_midi.song, vol); } diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 3ae9dc8ba1..9423ea6f9c 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1948,14 +1948,24 @@ static bool BuildTownHouse(Town *t, TileIndex tile) /* Generate a list of all possible houses that can be built. */ for (uint i = 0; i < HOUSE_MAX; i++) { const HouseSpec *hs = GetHouseSpecs(i); + /* Verify that the candidate house spec matches the current tile status */ - if ((~hs->building_availability & bitmask) == 0 && hs->enabled) { - /* Without NewHouses, all houses have probability '1' */ - uint cur_prob = (_loaded_newgrf_features.has_newhouses ? hs->probability : 1); - probability_max += cur_prob; - probs[num] = cur_prob; - houses[num++] = (HouseID)i; + if ((~hs->building_availability & bitmask) != 0 || !hs->enabled) continue; + + /* Don't let these counters overflow. Global counters are 32bit, there will never be that many houses. */ + if (hs->class_id != HOUSE_NO_CLASS) { + /* id_count is always <= class_count, so it doesn't need to be checked */ + if (t->building_counts.class_count[hs->class_id] == UINT16_MAX) continue; + } else { + /* If the house has no class, check id_count instead */ + if (t->building_counts.id_count[i] == UINT16_MAX) continue; } + + /* Without NewHouses, all houses have probability '1' */ + uint cur_prob = (_loaded_newgrf_features.has_newhouses ? hs->probability : 1); + probability_max += cur_prob; + probs[num] = cur_prob; + houses[num++] = (HouseID)i; } uint maxz = GetTileMaxZ(tile); diff --git a/src/yapf/yapf_common.hpp b/src/yapf/yapf_common.hpp index 43fdb68869..a0725a1ff6 100644 --- a/src/yapf/yapf_common.hpp +++ b/src/yapf/yapf_common.hpp @@ -160,7 +160,7 @@ public: int dy = abs(y1 - y2); int dmin = min(dx, dy); int dxy = abs(dx - dy); - int d = dmin * 7 + (dxy - 1) * (10 / 2); + int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2); n.m_estimate = n.m_cost + d; assert(n.m_estimate >= n.m_parent->m_estimate); return true; diff --git a/src/yapf/yapf_costrail.hpp b/src/yapf/yapf_costrail.hpp index f32b8388b5..81ef6a82a0 100644 --- a/src/yapf/yapf_costrail.hpp +++ b/src/yapf/yapf_costrail.hpp @@ -244,13 +244,13 @@ public: assert(v != NULL); assert(v->type == VEH_TRAIN); assert(v->u.rail.cached_total_length != 0); - int needed_platform_length = (v->u.rail.cached_total_length + TILE_SIZE - 1) / TILE_SIZE; - if (platform_length > needed_platform_length) { + int missing_platform_length = (v->u.rail.cached_total_length + TILE_SIZE - 1) / TILE_SIZE - platform_length; + if (missing_platform_length < 0) { /* apply penalty for longer platform than needed */ - cost += Yapf().PfGetSettings().rail_longer_platform_penalty; - } else if (needed_platform_length > platform_length) { + cost += Yapf().PfGetSettings().rail_longer_platform_penalty + Yapf().PfGetSettings().rail_longer_platform_per_tile_penalty * -missing_platform_length; + } else if (missing_platform_length > 0) { /* apply penalty for shorter platform than needed */ - cost += Yapf().PfGetSettings().rail_shorter_platform_penalty; + cost += Yapf().PfGetSettings().rail_shorter_platform_penalty + Yapf().PfGetSettings().rail_shorter_platform_per_tile_penalty * missing_platform_length; } return cost; } diff --git a/src/yapf/yapf_ship.cpp b/src/yapf/yapf_ship.cpp index 901545838a..36b0b00762 100644 --- a/src/yapf/yapf_ship.cpp +++ b/src/yapf/yapf_ship.cpp @@ -113,11 +113,11 @@ public: FORCEINLINE bool PfCalcCost(Node& n, const TrackFollower *tf) { /* base tile cost depending on distance */ - int c = IsDiagonalTrackdir(n.GetTrackdir()) ? 10 : 7; + int c = IsDiagonalTrackdir(n.GetTrackdir()) ? YAPF_TILE_LENGTH : YAPF_TILE_CORNER_LENGTH; /* additional penalty for curves */ if (n.m_parent != NULL && n.GetTrackdir() != NextTrackdir(n.m_parent->GetTrackdir())) { /* new trackdir does not match the next one when going straight */ - c += 10; + c += YAPF_TILE_LENGTH; } c += YAPF_TILE_LENGTH * tf->m_tiles_skipped;