diff --git a/bin/ai/regression/regression.txt b/bin/ai/regression/regression.txt index c5b65d8638..6dd6b1e098 100644 --- a/bin/ai/regression/regression.txt +++ b/bin/ai/regression/regression.txt @@ -7821,97 +7821,99 @@ 19693 => 8 --TileList_IndustryProducing-- - Count(): 90 + Count(): 92 Location ListDump: - 46149 => 14 - 46146 => 14 - 45894 => 14 - 45889 => 14 - 45638 => 14 - 45633 => 14 - 45382 => 14 - 45377 => 14 - 45126 => 12 - 45121 => 12 - 44869 => 12 - 44868 => 12 - 44867 => 12 - 44866 => 12 - 46150 => 11 - 46145 => 11 - 46405 => 10 - 46404 => 10 - 46403 => 10 - 46402 => 10 - 45895 => 9 - 45888 => 9 - 45639 => 9 - 45632 => 9 - 45383 => 9 - 45376 => 9 - 44870 => 9 - 44865 => 9 - 46406 => 8 - 46401 => 8 - 45127 => 8 - 45120 => 8 - 44613 => 8 - 44612 => 8 - 44611 => 8 - 44610 => 8 - 46151 => 7 - 46144 => 7 - 46661 => 6 - 46660 => 6 - 46659 => 6 - 46658 => 6 - 44871 => 6 - 44864 => 6 - 44614 => 6 - 44609 => 6 - 46662 => 5 - 46657 => 5 - 46407 => 5 - 46400 => 5 - 45896 => 4 - 45887 => 4 - 45640 => 4 - 45631 => 4 - 45384 => 4 - 45375 => 4 - 45128 => 4 - 45119 => 4 - 44615 => 4 - 44608 => 4 - 44357 => 4 - 44356 => 4 - 44355 => 4 - 44354 => 4 - 46663 => 3 - 46656 => 3 - 46152 => 3 - 46143 => 3 - 44872 => 3 - 44863 => 3 - 44358 => 3 - 44353 => 3 - 46918 => 2 - 46917 => 2 - 46916 => 2 - 46915 => 2 - 46914 => 2 - 46913 => 2 - 46408 => 2 - 46399 => 2 - 44616 => 2 - 44607 => 2 - 44359 => 2 - 44352 => 2 + 46920 => 1 46919 => 1 + 46918 => 1 + 46917 => 1 + 46916 => 1 + 46915 => 1 + 46914 => 1 + 46913 => 1 46912 => 1 + 46911 => 1 46664 => 1 + 46663 => 1 + 46662 => 1 + 46661 => 1 + 46660 => 1 + 46659 => 1 + 46658 => 1 + 46657 => 1 + 46656 => 1 46655 => 1 + 46408 => 1 + 46407 => 1 + 46406 => 1 + 46405 => 1 + 46404 => 1 + 46403 => 1 + 46402 => 1 + 46401 => 1 + 46400 => 1 + 46399 => 1 + 46152 => 1 + 46151 => 1 + 46150 => 1 + 46149 => 1 + 46146 => 1 + 46145 => 1 + 46144 => 1 + 46143 => 1 + 45896 => 1 + 45895 => 1 + 45894 => 1 + 45889 => 1 + 45888 => 1 + 45887 => 1 + 45640 => 1 + 45639 => 1 + 45638 => 1 + 45633 => 1 + 45632 => 1 + 45631 => 1 + 45384 => 1 + 45383 => 1 + 45382 => 1 + 45377 => 1 + 45376 => 1 + 45375 => 1 + 45128 => 1 + 45127 => 1 + 45126 => 1 + 45121 => 1 + 45120 => 1 + 45119 => 1 + 44872 => 1 + 44871 => 1 + 44870 => 1 + 44869 => 1 + 44868 => 1 + 44867 => 1 + 44866 => 1 + 44865 => 1 + 44864 => 1 + 44863 => 1 + 44616 => 1 + 44615 => 1 + 44614 => 1 + 44613 => 1 + 44612 => 1 + 44611 => 1 + 44610 => 1 + 44609 => 1 + 44608 => 1 + 44607 => 1 44360 => 1 + 44359 => 1 + 44358 => 1 + 44357 => 1 + 44356 => 1 + 44355 => 1 + 44354 => 1 + 44353 => 1 + 44352 => 1 44351 => 1 --TileList_StationType-- diff --git a/src/ai/api/ai_changelog.hpp b/src/ai/api/ai_changelog.hpp index 23b9d15739..7abe9023f9 100644 --- a/src/ai/api/ai_changelog.hpp +++ b/src/ai/api/ai_changelog.hpp @@ -91,6 +91,12 @@ * vehicle of that type in your company, regardless if it's still buildable * or not. AIEngine::IsBuildable returns only true when you can actually * build an engine. + * \li AITile::GetCargoProduction will now return the number of producers, + * including houses instead the number of producing tiles. This means that + * also industries that do not have a tile within the radius, but where + * the search bounding box and the industry's bounding box intersect, are + * counted. Previously these industries (and their cargos), although they + * produced cargo for a station at the given location, were not returned. * * \b 0.7.5 * diff --git a/src/ai/api/ai_tile.hpp b/src/ai/api/ai_tile.hpp index 6b254899f0..9ba0df0316 100644 --- a/src/ai/api/ai_tile.hpp +++ b/src/ai/api/ai_tile.hpp @@ -309,9 +309,8 @@ public: static int32 GetCargoAcceptance(TileIndex tile, CargoID cargo_type, int width, int height, int radius); /** - * Checks how many tiles in the radius produces this cargo. - * It creates a radius around the tile, and adds up all tiles that produce - * this cargo. + * Checks how many producers in the radius produces this cargo. + * It creates a radius around the tile, and counts all producer of this cargo. * @param tile The tile to check on. * @param cargo_type The cargo to check the production of. * @param width The width of the station. @@ -321,8 +320,7 @@ public: * @pre width > 0. * @pre height > 0. * @pre radius >= 0. - * @return The tiles that produce this cargo within radius of the tile. - * @note Town(houses) are not included in the value. + * @return The number of producers that produce this cargo within radius of the tile. */ static int32 GetCargoProduction(TileIndex tile, CargoID cargo_type, int width, int height, int radius); diff --git a/src/ai/api/ai_tilelist.cpp b/src/ai/api/ai_tilelist.cpp index 12ebb1eade..8513ba17c6 100644 --- a/src/ai/api/ai_tilelist.cpp +++ b/src/ai/api/ai_tilelist.cpp @@ -90,13 +90,11 @@ AITileList_IndustryProducing::AITileList_IndustryProducing(IndustryID industry_i const Industry *i = ::Industry::Get(industry_id); /* Check if this industry produces anything */ - { - bool cargo_produces = false; - for (byte j = 0; j < lengthof(i->produced_cargo); j++) { - if (i->produced_cargo[j] != CT_INVALID) cargo_produces = true; - } - if (!cargo_produces) return; + bool cargo_produces = false; + for (byte j = 0; j < lengthof(i->produced_cargo); j++) { + if (i->produced_cargo[j] != CT_INVALID) cargo_produces = true; } + if (!cargo_produces) return; if (!_settings_game.station.modified_catchment) radius = CA_UNMODIFIED; @@ -105,17 +103,6 @@ AITileList_IndustryProducing::AITileList_IndustryProducing(IndustryID industry_i /* Exclude all tiles that belong to this industry */ if (::IsTileType(cur_tile, MP_INDUSTRY) && ::GetIndustryIndex(cur_tile) == industry_id) continue; - /* Only add the tile if it produces the cargo (a bug in OpenTTD makes this - * inconsitance). */ - CargoArray produced = ::GetProductionAroundTiles(cur_tile, 1, 1, radius); - { - bool cargo_produces = false; - for (byte j = 0; j < lengthof(i->produced_cargo); j++) { - if (i->produced_cargo[j] != CT_INVALID && produced[i->produced_cargo[j]] != 0) cargo_produces = true; - } - if (!cargo_produces) continue; - } - this->AddTile(cur_tile); } } diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 82c1ef8559..4a414ea83b 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -924,16 +924,6 @@ static TrackStatus GetTileTrackStatus_Industry(TileIndex tile, TransportType mod return 0; } -static void AddProducedCargo_Industry(TileIndex tile, CargoArray &produced) -{ - const Industry *i = Industry::GetByTile(tile); - - for (uint j = 0; j < lengthof(i->produced_cargo); j++) { - CargoID cargo = i->produced_cargo[j]; - if (cargo != CT_INVALID) produced[cargo]++; - } -} - static void ChangeTileOwner_Industry(TileIndex tile, Owner old_owner, Owner new_owner) { /* If the founder merges, the industry was created by the merged company */ @@ -2468,7 +2458,7 @@ extern const TileTypeProcs _tile_type_industry_procs = { AnimateTile_Industry, // animate_tile_proc TileLoop_Industry, // tile_loop_proc ChangeTileOwner_Industry, // change_tile_owner_proc - AddProducedCargo_Industry, // add_produced_cargo_proc + NULL, // add_produced_cargo_proc NULL, // vehicle_enter_tile_proc GetFoundation_Industry, // get_foundation_proc TerraformTile_Industry, // terraform_tile_proc diff --git a/src/station.cpp b/src/station.cpp index a3c58052ad..659ece367b 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -539,6 +539,30 @@ void TileArea::Add(TileIndex to_add) this->h = ey - sy + 1; } +bool TileArea::Intersects(const TileArea &ta) const +{ + if (ta.w == 0 || this->w == 0) return false; + + assert(ta.w != 0 && ta.h != 0 && this->w != 0 && this->h != 0); + + uint left1 = TileX(this->tile); + uint top1 = TileY(this->tile); + uint right1 = left1 + this->w - 1; + uint bottom1 = top1 + this->h - 1; + + uint left2 = TileX(ta.tile); + uint top2 = TileY(ta.tile); + uint right2 = left2 + ta.w - 1; + uint bottom2 = top2 + ta.h - 1; + + return !( + left2 > right1 || + right2 < left1 || + top2 > bottom1 || + bottom2 < top1 + ); +} + void InitializeStations() { diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 8b7bf53455..b66ccafb51 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -485,10 +485,25 @@ CargoArray GetProductionAroundTiles(TileIndex tile, int w, int h, int rad) assert(w > 0); assert(h > 0); - for (int yc = y1; yc != y2; yc++) { - for (int xc = x1; xc != x2; xc++) { - TileIndex tile = TileXY(xc, yc); - AddProducedCargo(tile, produced); + TileArea ta(TileXY(x1, y1), TileXY(x2 - 1, y2 - 1)); + + /* Loop over all tiles to get the produced cargo of + * everything except industries */ + TILE_AREA_LOOP(tile, ta) AddProducedCargo(tile, produced); + + /* Loop over the industries. They produce cargo for + * anything that is within 'rad' from their bounding + * box. As such if you have e.g. a oil well the tile + * area loop might not hit an industry tile while + * the industry would produce cargo for the station. + */ + const Industry *i; + FOR_ALL_INDUSTRIES(i) { + if (!ta.Intersects(i->location)) continue; + + for (uint j = 0; j < lengthof(i->produced_cargo); j++) { + CargoID cargo = i->produced_cargo[j]; + if (cargo != CT_INVALID) produced[cargo]++; } } diff --git a/src/tilearea_type.h b/src/tilearea_type.h index 8bac2fbbf7..6c2639cff4 100644 --- a/src/tilearea_type.h +++ b/src/tilearea_type.h @@ -53,6 +53,13 @@ struct TileArea { this->w = 0; this->h = 0; } + + /** + * Does this tile area intersect with another? + * @param ta the other tile area to check against. + * @return true if they intersect. + */ + bool Intersects(const TileArea &ta) const; }; #endif /* TILEAREA_TYPE_H */