changeset 14178:e02ce213bb0f draft

(svn r18726) -Fix [FS#3463]: with non-uniform industries the 'supplies' text when building a station could be incorrect (missing a cargo) -Change [NoAI]: AITile::GetCargoProduction now returns the number of producers and not the number of tiles of producers. -Fix [NoAI]: AITileList_IndustryProducing would omit some tiles for at which a station would get cargo.
author rubidium <rubidium@openttd.org>
date Mon, 04 Jan 2010 21:10:20 +0000
parents 3703b52f8d36
children 11c99e48d60b
files bin/ai/regression/regression.txt src/ai/api/ai_changelog.hpp src/ai/api/ai_tile.hpp src/ai/api/ai_tilelist.cpp src/industry_cmd.cpp src/station.cpp src/station_cmd.cpp src/tilearea_type.h
diffstat 8 files changed, 151 insertions(+), 122 deletions(-) [+]
line wrap: on
line diff
--- 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--
--- 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
  *
--- a/src/ai/api/ai_tile.hpp
+++ b/src/ai/api/ai_tile.hpp
@@ -309,9 +309,8 @@
 	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 @@
 	 * @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);
 
--- a/src/ai/api/ai_tilelist.cpp
+++ b/src/ai/api/ai_tilelist.cpp
@@ -90,13 +90,11 @@
 	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 @@
 		/* 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);
 	}
 }
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -924,16 +924,6 @@
 	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 @@
 	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
--- a/src/station.cpp
+++ b/src/station.cpp
@@ -539,6 +539,30 @@
 	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()
 {
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -485,10 +485,25 @@
 	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]++;
 		}
 	}
 
--- a/src/tilearea_type.h
+++ b/src/tilearea_type.h
@@ -53,6 +53,13 @@
 		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 */