changeset 19220:87d0ea2d8725 draft

(svn r24105) -Feature: Be more careful with the population of a small town while placing a statue.
author alberth <alberth@openttd.org>
date Sun, 08 Apr 2012 17:30:20 +0000
parents b5a91589a5ae
children dcb312814e3f
files src/town_cmd.cpp
diffstat 1 files changed, 19 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -2720,8 +2720,9 @@
 /** Structure for storing data while searching the best place to build a statue. */
 struct StatueBuildSearchData {
 	TileIndex best_position; ///< Best position found so far.
-
-	StatueBuildSearchData(TileIndex best_pos) : best_position(best_pos) { }
+	int tile_count;          ///< Number of tiles tried.
+
+	StatueBuildSearchData(TileIndex best_pos, int count) : best_position(best_pos), tile_count(count) { }
 };
 
 /**
@@ -2732,7 +2733,10 @@
  */
 static bool SearchTileForStatue(TileIndex tile, void *user_data)
 {
+	static const int STATUE_NUMBER_INNER_TILES = 25; // Number of tiles int the center of the city, where we try to protect houses.
+
 	StatueBuildSearchData *statue_data = (StatueBuildSearchData *)user_data;
+	statue_data->tile_count++;
 
 	/* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
 	if (IsSteepSlope(GetTileSlope(tile))) return false;
@@ -2747,6 +2751,18 @@
 
 	bool house = IsTileType(tile, MP_HOUSE);
 
+	/* Searching inside the inner circle. */
+	if (statue_data->tile_count <= STATUE_NUMBER_INNER_TILES) {
+		/* Save first house in inner circle. */
+		if (house && statue_data->best_position == INVALID_TILE && TryClearTile(tile)) {
+			statue_data->best_position = tile;
+		}
+
+		/* If we have reached the end of the inner circle, and have a saved house, terminate the search. */
+		return statue_data->tile_count == STATUE_NUMBER_INNER_TILES && statue_data->best_position != INVALID_TILE;
+	}
+
+	/* Searching outside the circle, just pick the first possible spot. */
 	statue_data->best_position = tile; // Is optimistic, the condition below must also hold.
 	return house && TryClearTile(tile);
 }
@@ -2763,7 +2779,7 @@
 	if (!Object::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_OBJECTS);
 
 	TileIndex tile = t->xy;
-	StatueBuildSearchData statue_data(INVALID_TILE);
+	StatueBuildSearchData statue_data(INVALID_TILE, 0);
 	if (!CircularTileSearch(&tile, 9, SearchTileForStatue, &statue_data)) return_cmd_error(STR_ERROR_STATUE_NO_SUITABLE_PLACE);
 
 	if (flags & DC_EXEC) {