diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index 6279165900..d536074eee 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -145,6 +145,23 @@ uint32 IndustriesScopeResolver::GetCountAndDistanceOfClosestInstance(byte param_ * In either case, just do the regular var67 */ if (mask & 0xFFFF) closest_dist = this->GetClosestIndustry(ind_index); if (mask & 0xFF0000) count = ClampTo(Industry::GetIndustryTypeCount(ind_index)); + } else if (layout_filter == 0 && town_filter) { + /* Count only those which match the same industry type and town */ + std::unique_ptr &cache = this->town_location_distance_cache; + if (cache == nullptr) { + cache = std::make_unique(); + MemSetT(cache->distances, 0xFF, NUM_INDUSTRYTYPES); + MemSetT(cache->counts, 0, NUM_INDUSTRYTYPES); + for (const Industry *i : Industry::Iterate()) { + if (i == this->industry || i->type >= NUM_INDUSTRYTYPES || i->town != this->industry->town) continue; + + uint dist = DistanceManhattan(this->tile, i->location.tile); + if (dist < (uint)cache->distances[i->type]) cache->distances[i->type] = (uint16)dist; + cache->counts[i->type] = ClampTo(cache->counts[i->type] + 1); + } + } + closest_dist = cache->distances[ind_index]; + count = cache->counts[ind_index]; } else { /* Count only those who match the same industry type and layout filter * Unfortunately, we have to do it manually */ diff --git a/src/newgrf_industries.h b/src/newgrf_industries.h index 65af1e90dc..fbd89dafe8 100644 --- a/src/newgrf_industries.h +++ b/src/newgrf_industries.h @@ -16,6 +16,11 @@ struct IndustryLocationDistanceCache { uint16 distances[NUM_INDUSTRYTYPES]; }; +struct IndustryLocationDistanceAndCountCache { + uint16 distances[NUM_INDUSTRYTYPES]; + uint8 counts[NUM_INDUSTRYTYPES]; +}; + /** Resolver for industry scopes. */ struct IndustriesScopeResolver : public ScopeResolver { TileIndex tile; ///< Tile owned by the industry. @@ -24,6 +29,7 @@ struct IndustriesScopeResolver : public ScopeResolver { IndustryType type; ///< Type of the industry. mutable std::unique_ptr location_distance_cache; + mutable std::unique_ptr town_location_distance_cache; /** * Scope resolver for industries.