← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/tibor-ai4 into lp:widelands

 

Tibor Bamhor has proposed merging lp:~widelands-dev/widelands/tibor-ai4 into lp:widelands.

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/tibor-ai4/+merge/226029

Based on discussion with other developers, I created new branch and plainly copied files from tibor-ai3 that differed
-- 
https://code.launchpad.net/~widelands-dev/widelands/tibor-ai4/+merge/226029
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/tibor-ai4 into lp:widelands.
=== modified file 'src/ai/ai_help_structs.cc'
--- src/ai/ai_help_structs.cc	2014-07-03 19:26:30 +0000
+++ src/ai/ai_help_structs.cc	2014-07-08 19:41:26 +0000
@@ -37,7 +37,7 @@
 // CheckStepRoadAI
 
 bool CheckStepRoadAI::allowed(Map& map, FCoords, FCoords end, int32_t, CheckStep::StepId const id)
-	const {
+   const {
 	uint8_t endcaps = player_->get_buildcaps(end);
 
 	// Calculate cost and passability

=== modified file 'src/ai/ai_help_structs.h'
--- src/ai/ai_help_structs.h	2014-07-05 16:41:51 +0000
+++ src/ai/ai_help_structs.h	2014-07-08 19:41:26 +0000
@@ -70,6 +70,21 @@
 	}
 };
 
+struct FindNodeEnemiesBuilding {
+	bool accept(const Map&, const FCoords& fc) const {
+		// we are looking for fields we can walk on
+		// and owned by hostile player.
+		return (fc.field->get_immovable()) && fc.field->get_owned_by() != 0 &&
+		       player->is_hostile(*game.get_player(fc.field->get_owned_by()));
+	}
+
+	Player* player;
+	Game& game;
+
+	FindNodeEnemiesBuilding(Player* p, Game& g) : player(p), game(g) {
+	}
+};
+
 struct FindNodeUnowned {
 	bool accept(const Map&, const FCoords& fc) const {
 		// when looking for unowned terrain to acquire, we are actually
@@ -105,10 +120,12 @@
 };
 
 struct FindNodeWater {
-	FindNodeWater(const World& world) : world_(world) {}
+	FindNodeWater(const World& world) : world_(world) {
+	}
 
 	bool accept(const Map& /* map */, const FCoords& coord) const {
-		return (world_.terrain_descr(coord.field->terrain_d()).get_is() & TerrainDescription::WATER) ||
+		return (world_.terrain_descr(coord.field->terrain_d()).get_is() &
+		        TerrainDescription::WATER) ||
 		       (world_.terrain_descr(coord.field->terrain_r()).get_is() & TerrainDescription::WATER);
 	}
 
@@ -116,6 +133,7 @@
 	const World& world_;
 };
 
+
 struct FindNodeWithFlagOrRoad {
 	Economy* economy;
 	bool accept(const Map&, FCoords) const;
@@ -174,10 +192,14 @@
 	bool enemy_nearby_;
 
 	uint8_t unowned_land_nearby_;
+	// to identify that field is too close to border and no production building should be built there
+	bool near_border_;
 	uint8_t unowned_mines_pots_nearby_;
 	uint8_t trees_nearby_;
 	uint8_t stones_nearby_;
 	int8_t water_nearby_;
+	int8_t fish_nearby_;
+	int8_t critters_nearby_;
 	int8_t ground_water_;  // used by wells
 	uint8_t space_consumers_nearby_;
 	// to manage the military better following variables exists:
@@ -205,6 +227,7 @@
 	     preferred_(false),
 	     enemy_nearby_(0),
 	     unowned_land_nearby_(0),
+	     near_border_(false),
 	     trees_nearby_(0),
 	     // explanation of starting values
 	     // this is done to save some work for AI (CPU utilization)
@@ -215,6 +238,8 @@
 	     // non-negative, water is not recaldulated
 	     stones_nearby_(1),
 	     water_nearby_(-1),
+	     fish_nearby_(-1),
+	     critters_nearby_(-1),
 	     ground_water_(1),
 	     space_consumers_nearby_(0),
 	     military_capacity_(0),
@@ -267,17 +292,22 @@
 		MINE
 	} type;
 
-	bool is_basic_;  // is a "must" to have for the ai
+	bool is_basic_;       // is a "must" to have for the ai
+	bool is_food_basic_;  // few food producer to be built sooner
 	bool prod_build_material_;
 	bool plants_trees_;
 	bool recruitment_;  // is "producing" workers?
 	bool is_buildable_;
-	bool need_trees_;      // lumberjack = true
-	bool need_stones_;     // quarry = true
-	bool mines_marble_;    // need to distinquish mines_ that produce marbles
-	bool mines_water_;     // wells
-	bool need_water_;      // fisher, fish_breeder = true
-	bool space_consumer_;  // farm, vineyard... = true
+	bool need_trees_;          // lumberjack = true
+	bool need_stones_;         // quarry = true
+	bool mines_marble_;        // need to distinquish mines_ that produce marbles
+	bool mines_water_;         // wells
+	bool need_water_;          // fisher, fish_breeder = true
+	bool is_hunter_;           // need to identify hunters
+	bool space_consumer_;      // farm, vineyard... = true
+	bool expansion_type_;      // military building used that can be used to control area
+	bool fighting_type_;       // military building built near enemies
+	bool mountain_conqueror_;  // military building built near mountains
 
 	bool unoccupied_;  //
 
@@ -309,8 +339,9 @@
 };
 
 struct ProductionSiteObserver {
-	Widelands::OPtr<Widelands::ProductionSite> site;
+	Widelands::ProductionSite* site;
 	int32_t built_time_;
+	int32_t unoccupied_till_;
 	uint8_t stats_zero_;
 	BuildingObserver* bo;
 };
@@ -319,6 +350,9 @@
 	Widelands::MilitarySite* site;
 	BuildingObserver* bo;
 	uint8_t checks;
+	// when considering attack most military sites are inside territory and should be skipped during
+	// evaluation
+	bool enemies_nearby;
 };
 
 struct WareObserver {

=== modified file 'src/ai/ai_hints.cc'
--- src/ai/ai_hints.cc	2014-06-21 15:17:04 +0000
+++ src/ai/ai_hints.cc	2014-07-08 19:41:26 +0000
@@ -19,7 +19,6 @@
 
 #include "ai/ai_hints.h"
 
-#include <cstdlib>
 #include <cstring>
 
 #include "profile/profile.h"
@@ -30,22 +29,26 @@
 }
 
 BuildingHints::BuildingHints(Section* const section)
-	: renews_map_resource(nullptr),
-	mines_(nullptr),
-	basic_(section ? section->get_bool("is_basic") : false),
-	build_material_(section ? section->get_bool("build_material") : true),
-	log_producer_(section ? section->get_bool("logproducer") : false),
-	stone_producer_(section ? section->get_bool("stoneproducer") : false),
-	marble_producer_(section ? section->get_bool("marbleproducer") : false),
-	needs_water_(section ? section->get_bool("needs_water") : false),
-	mines_water_(section ? section->get_bool("mines_water") : false),
-	recruitment_(section ? section->get_bool("recruitment") : false),
-	space_consumer_(section ? section->get_bool("space_consumer") : false),
-	mines_percent_(section ? section->get_int("mines_percent", 100) : 0) {
-		if (section) {
-			if (char const* const s = section->get_string("renews_map_resource"))
-				renews_map_resource = strdup(s);
-			if (char const* const s = section->get_string("mines"))
-				mines_ = strdup(s);
-		}
+   : renews_map_resource(nullptr),
+     mines_(nullptr),
+     basic_(section ? section->get_bool("is_basic") : false),
+     food_basic_(section ? section->get_bool("is_food_basic") : false),
+     build_material_(section ? section->get_bool("build_material") : true),
+     log_producer_(section ? section->get_bool("logproducer") : false),
+     stone_producer_(section ? section->get_bool("stoneproducer") : false),
+     marble_producer_(section ? section->get_bool("marbleproducer") : false),
+     needs_water_(section ? section->get_bool("needs_water") : false),
+     mines_water_(section ? section->get_bool("mines_water") : false),
+     recruitment_(section ? section->get_bool("recruitment") : false),
+     space_consumer_(section ? section->get_bool("space_consumer") : false),
+     expansion_(section ? section->get_bool("expansion") : false),
+     fighting_(section ? section->get_bool("fighting") : false),
+     mountain_conqueror_(section ? section->get_bool("mountain_conqueror") : false),
+     mines_percent_(section ? section->get_int("mines_percent", 100) : 0) {
+	if (section) {
+		if (char const* const s = section->get_string("renews_map_resource"))
+			renews_map_resource = strdup(s);
+		if (char const* const s = section->get_string("mines"))
+			mines_ = strdup(s);
 	}
+}

=== modified file 'src/ai/ai_hints.h'
--- src/ai/ai_hints.h	2014-07-05 16:41:51 +0000
+++ src/ai/ai_hints.h	2014-07-08 19:41:26 +0000
@@ -20,11 +20,10 @@
 #ifndef WL_AI_AI_HINTS_H
 #define WL_AI_AI_HINTS_H
 
-#include <stdint.h>
-
+#include <SDL_types.h>
 #include <boost/noncopyable.hpp>
 
-class Section;
+struct Section;
 
 /// This struct is used to read out the data given in [aihints] section of a
 /// buildings conf file. It is used to tell the computer player about the
@@ -45,6 +44,10 @@
 		return basic_;
 	}
 
+	bool is_food_basic() const {
+		return food_basic_;
+	}
+
 	bool prod_build_material() const {
 		return build_material_;
 	}
@@ -76,6 +79,15 @@
 	bool is_space_consumer() const {
 		return space_consumer_;
 	}
+	bool is_expansion_type() const {
+		return expansion_;
+	}
+	bool is_fighting_type() const {
+		return fighting_;
+	}
+	bool is_mountain_conqueror() const {
+		return mountain_conqueror_;
+	}
 
 	uint8_t get_mines_percent() const {
 		return mines_percent_;
@@ -85,6 +97,7 @@
 	char* renews_map_resource;
 	char* mines_;
 	bool basic_;
+	bool food_basic_;
 	bool build_material_;  // whether the building produces build material
 	bool log_producer_;
 	bool stone_producer_;
@@ -93,6 +106,9 @@
 	bool mines_water_;
 	bool recruitment_;  // whether building recruits special workers
 	bool space_consumer_;
+	bool expansion_;
+	bool fighting_;
+	bool mountain_conqueror_;
 	uint8_t mines_percent_;
 };
 

=== modified file 'src/ai/defaultai.cc'
--- src/ai/defaultai.cc	2014-07-03 19:26:30 +0000
+++ src/ai/defaultai.cc	2014-07-08 19:41:26 +0000
@@ -16,8 +16,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
  */
-
-#include "ai/defaultai.h"
+/**
+ * Default AI
+ */
 
 #include <algorithm>
 #include <ctime>
@@ -25,12 +26,14 @@
 #include <typeinfo>
 
 #include "ai/ai_hints.h"
+#include "ai/defaultai.h"
 #include "base/log.h"
 #include "base/macros.h"
 #include "economy/economy.h"
 #include "economy/flag.h"
 #include "economy/road.h"
 #include "logic/constructionsite.h"
+#include "logic/findbob.h"
 #include "logic/findimmovable.h"
 #include "logic/findnode.h"
 #include "logic/map.h"
@@ -64,9 +67,14 @@
 constexpr bool kWoodDebug = false;
 constexpr bool kSpaceDebug = false;
 constexpr bool kStatDebug = false;
-constexpr bool kIdleDismantle = false;
+constexpr bool kIdleDismantle = true;
 constexpr bool kWellDebug = false;
+constexpr bool kHuntFishDebug = false;
+constexpr bool kAttackDebug = false;
 constexpr int kBaseInfrastructureTime = 20 * 60 * 1000;
+// buildings marked as is_food_basic will be forced after 15 minutes, even though their outputs are
+// not needed yet
+constexpr int kPrimaryFoodStartTime = 15 * 60 * 1000;
 
 using namespace Widelands;
 
@@ -144,7 +152,6 @@
 
 		if (construct_roads(gametime)) {
 			m_buildable_changed = true;
-			// m_mineable_changed = true;
 			return;
 		}
 	} else
@@ -159,11 +166,9 @@
 	// handled by the AI itself.
 	update_all_not_buildable_fields();
 
-	// IF defaultAI is AGGRESSIVE - we definitely should consider to attack as
-	// often as possible.
-	if (type == AGGRESSIVE)
-		if (next_attack_consideration_due_ <= gametime)
-			consider_attack(gametime);
+	// considering attack
+	if (next_attack_consideration_due_ <= gametime)
+		consider_attack(gametime);
 
 	// check if anything in the economies changed.
 	// This needs to be done before new buildings are placed, to ensure that no
@@ -199,12 +204,6 @@
 	if (check_militarysites(gametime))
 		return;
 
-	//  Finally consider military actions if defaultAI type is Aggressive or
-	// Normal.
-	if (!(type == DEFENSIVE))
-		if (next_attack_consideration_due_ <= gametime)
-			consider_attack(gametime);
-
 	// improve existing roads!
 	// This sounds important, but actually is not as important as the other
 	// actions are. Reasons are the following:
@@ -222,9 +221,10 @@
 
 /// called by Widelands game engine when an immovable changed
 void DefaultAI::receive(const NoteImmovable& note) {
-	if (note.lg == LOSE)
+	if (note.lg == LOSE) {
+
 		lose_immovable(*note.pi);
-	else
+	} else
 		gain_immovable(*note.pi);
 }
 
@@ -282,6 +282,7 @@
 		bo.current_stats_ = 0;
 		bo.unoccupied_ = false;
 		bo.is_basic_ = false;
+		bo.is_food_basic_ = false;
 		bo.is_buildable_ = bld.is_buildable();
 		bo.need_trees_ = bh.is_logproducer();
 		bo.need_stones_ = bh.is_stoneproducer();
@@ -290,7 +291,9 @@
 		bo.mines_water_ = bh.mines_water();
 		bo.recruitment_ = bh.for_recruitment();
 		bo.space_consumer_ = bh.is_space_consumer();
-
+		bo.expansion_type_ = bh.is_expansion_type();
+		bo.fighting_type_ = bh.is_fighting_type();
+		bo.mountain_conqueror_ = bh.is_mountain_conqueror();
 		if (char const* const s = bh.get_renews_map_resource()) {
 			bo.production_hint_ = tribe->safe_ware_index(s);
 
@@ -326,8 +329,15 @@
 			}
 
 			bo.is_basic_ = bh.is_basic();
+			bo.is_food_basic_ = bh.is_food_basic();
 			bo.prod_build_material_ = bh.prod_build_material();
 
+			// here we identify hunters
+			if (bo.outputs_.size() == 1 and tribe->safe_ware_index("meat") == bo.outputs_.at(0)) {
+				bo.is_hunter_ = true;
+			} else
+				bo.is_hunter_ = false;
+
 			continue;
 		}
 
@@ -491,16 +501,24 @@
 	FindNodeUnowned find_unowned(player, game());
 	FindNodeUnownedMineable find_unowned_mines_pots(player, game());
 	Player_Number const pn = player->player_number();
+	const World& world = game().world();
 	field.unowned_land_nearby_ =
 	   map.find_fields(Area<FCoords>(field.coords, range), nullptr, find_unowned);
 
-	if (field.unowned_land_nearby_ > 2)  // 2 is 'reasonably low' number here
+	field.near_border_ = false;
+	if (field.unowned_land_nearby_ > 0) {
+		if (map.find_fields(Area<FCoords>(field.coords, 4), nullptr, find_unowned) > 0)
+			field.near_border_ = true;
+	}
+
+	// to save some CPU
+	if (mines_.size() > 8 and game().get_gametime() % 3 > 0)
+		field.unowned_mines_pots_nearby_ = 0;
+	else
 		field.unowned_mines_pots_nearby_ = map.find_fields(
-		   Area<FCoords>(field.coords, range + 2),
+		   Area<FCoords>(field.coords, range + 4),
 		   nullptr,
 		   find_unowned_mines_pots);  //+2: a mine can mine raw materials from some range
-	else
-		field.unowned_mines_pots_nearby_ = 0;
 
 	// collect information about resources in the area
 	std::vector<ImmovableFound> immovables;
@@ -525,13 +543,30 @@
 		field.consumers_nearby_.clear();
 		field.consumers_nearby_.resize(wares.size());
 		std::vector<Coords> water_list;
+		std::vector<Coords> resource_list;
+		std::vector<Bob*> critters_list;
 
 		if (field.water_nearby_ == -1) {  //-1 means "value has never been calculated"
 			FindNodeWater find_water(game().world());
-			map.find_fields(Area<FCoords>(field.coords, 4), &water_list, find_water);
+			map.find_fields(Area<FCoords>(field.coords, 6), &water_list, find_water);
 			field.water_nearby_ = water_list.size();
 		}
 
+		// counting fields with fish
+		if (field.water_nearby_ > 0 and game().get_gametime() % 10 == 0) {
+			map.find_fields(Area<FCoords>(field.coords, 6),
+			                &resource_list,
+			                FindNodeResource(world.get_resource("fish")));
+			field.fish_nearby_ = resource_list.size();
+		}
+
+		// counting fields with critters (game)
+		// not doing this allways, this does not change fast
+		if (game().get_gametime() % 10 == 0) {
+			map.find_bobs(Area<FCoords>(field.coords, 6), &critters_list, FindBobCritter());
+			field.critters_nearby_ = critters_list.size();
+		}
+
 		FCoords fse;
 		map.get_neighbour(field.coords, WALK_SE, &fse);
 
@@ -590,13 +625,10 @@
 			}
 		}
 
-		//// ground water is not renewable and its amount can only fall, we will count them only if
-		/// previous state si nonzero
+		// ground water is not renewable and its amount can only fall, we will count them only if
+		// previous state si nonzero
 		if (field.ground_water_ > 0) {
-			field.ground_water_ =
-			   field.coords.field->get_resources_amount();  // field->get_resources();
-
-			// log(" RESOURCE DEBUG: %2d",field.get_resources());
+			field.ground_water_ = field.coords.field->get_resources_amount();
 		}
 	}
 
@@ -658,7 +690,7 @@
 				if (v > 0 and dist > 0) {
 					if (kMilitScoreDebug)
 						log(" FIELD SCORE:  testing near military building at %3dx%3d, capacity: %d, "
-						    "loneliness:%3f (%2d:%2d), stationed: %" PRIuS "\n",
+						    "loneliness:%3f (%2d:%2d), stationed: %1d\n",
 						    immovables.at(i).coords.x,
 						    immovables.at(i).coords.y,
 						    militarysite->maxSoldierCapacity(),
@@ -738,45 +770,34 @@
 
 	// Check all available productionsites
 	for (uint32_t i = 0; i < productionsites.size(); ++i) {
-		ProductionSiteObserver& productionsite_observer = productionsites.front();
-		// TODO(sirver): Popping here means that we HAVE to push another thing at
-		// the end or our loop will not do the right think. This is terrible
-		// design. It would be much better to push to a new vector and swap the
-		// productionsites' content after the loop. I refuse to fix this though.
+		assert(productionsites.front().bo->cnt_built_ > 0);
+		// Add statistics value
+		productionsites.front().bo->current_stats_ +=
+		   productionsites.front().site->get_crude_statistics();
+		if (kStatDebug and abs(productionsites.front().site->get_crude_statistics() -
+		                       productionsites.front().site->get_statistics_percent()) > 50)
+			log(" STAT DEBUG: %15s (%3dx%3d): crude statistic: %3d vs official statistics: %3d\n",
+			    productionsites.front().site->name().c_str(),
+			    productionsites.front().site->get_position().x,
+			    productionsites.front().site->get_position().y,
+			    productionsites.front().site->get_crude_statistics(),
+			    productionsites.front().site->get_statistics_percent());
+		// Check whether this building is completely occupied
+		productionsites.front().bo->unoccupied_ |= !productionsites.front().site->can_start_working();
+
+		// Now reorder the buildings
+		productionsites.push_back(productionsites.front());
 		productionsites.pop_front();
-
-		assert(productionsite_observer.bo->cnt_built_ > 0);
-
-		ProductionSite* productionsite = productionsite_observer.site.get(game());
-		if (productionsite != nullptr) {
-			// Add statistics value
-			productionsite_observer.bo->current_stats_ += productionsite->get_crude_statistics();
-			if (kStatDebug and abs(productionsite->get_crude_statistics() -
-			                       productionsite->get_statistics_percent()) > 50)
-				log(" STAT DEBUG: %15s (%3dx%3d): crude statistic: %3d vs official statistics: %3d\n",
-				    productionsite->name().c_str(),
-				    productionsite->get_position().x,
-				    productionsite->get_position().y,
-				    productionsite->get_crude_statistics(),
-				    productionsite->get_statistics_percent());
-			// Check whether this building is completely occupied
-			productionsite_observer.bo->unoccupied_ |= !productionsite->can_start_working();
-		}
-		// Now reorder the buildings
-		productionsites.push_back(productionsite_observer);
 	}
 
 	// for mines_ also
 	// Check all available productionsites
 	for (uint32_t i = 0; i < mines_.size(); ++i) {
 		assert(mines_.front().bo->cnt_built_ > 0);
-		ProductionSite* mine = mines_.front().site.get(game());
-		if (mine != nullptr) {
-			// Add statistics value
-			mines_.front().bo->current_stats_ += mine->get_statistics_percent();
-			// Check whether this building is completely occupied
-			mines_.front().bo->unoccupied_ |= !mine->can_start_working();
-		}
+		// Add statistics value
+		mines_.front().bo->current_stats_ += mines_.front().site->get_statistics_percent();
+		// Check whether this building is completely occupied
+		mines_.front().bo->unoccupied_ |= !mines_.front().site->can_start_working();
 		// Now reorder the buildings
 		mines_.push_back(mines_.front());
 		mines_.pop_front();
@@ -798,6 +819,8 @@
 // - buildings producing building material are preffered
 // - buildings identified as basic are preffered
 // - first bulding of a type is preffered
+// - buildings identified as 'direct food supplier' as built after 15 min.
+//   from game start
 // - if a bulding is upgradeable, second building is also preffered
 //   (there should be no upgrade when there are not two buildings of the same type)
 // - algorigthm is trying to take into account actual utlization of buildings
@@ -817,6 +840,7 @@
 	int32_t bulgarian_constant = 12;
 	std::vector<int32_t> spots_avail;
 	spots_avail.resize(4);
+	// uint16_t const pn = player_number();
 
 	for (int32_t i = 0; i < 4; ++i)
 		spots_avail.at(i) = 0;
@@ -826,57 +850,22 @@
 	     ++i)
 		++spots_avail.at((*i)->coords.field->nodecaps() & BUILDCAPS_SIZEMASK);
 
-	// calculating expand factor
-	int32_t expand_factor = 0;
-
-	if (type != DEFENSIVE) {
-		++expand_factor;
-
-		// check space and set the need for expansion
-		if (spots_avail.at(BUILDCAPS_BIG) < static_cast<uint16_t>(2 + (productionsites.size() / 50)))
-			expand_factor += 2;
-
-		if (spots_avail.at(BUILDCAPS_MEDIUM) + spots_avail.at(BUILDCAPS_BIG) <
-		    static_cast<uint16_t>(4 + (productionsites.size() / 50)))
-			expand_factor += type;
-
-		spots = spots_avail.at(BUILDCAPS_SMALL);
-		spots += spots_avail.at(BUILDCAPS_MEDIUM);
-		spots += spots_avail.at(BUILDCAPS_BIG);
-
-		if (type == AGGRESSIVE)
-			spots -= militarysites.size() / 20;
-
-		if (spots < 16)
-			expand_factor *= 2;
-
-		if ((type == AGGRESSIVE) && spots < 32)
-			expand_factor *= 2;
-	} else {
-		// check space and set the need for expansion
-		if (spots_avail.at(BUILDCAPS_BIG) < 7)
-			++expand_factor;
-
-		if (spots_avail.at(BUILDCAPS_MEDIUM) + spots_avail.at(BUILDCAPS_BIG) < 12)
-			++expand_factor;
-
-		if (spots_avail.at(BUILDCAPS_SMALL) + spots_avail.at(BUILDCAPS_MEDIUM) +
-		       spots_avail.at(BUILDCAPS_BIG) <
-		    16)
-			expand_factor *= 3;
-	}
+	spots = spots_avail.at(BUILDCAPS_SMALL);
+	spots += spots_avail.at(BUILDCAPS_MEDIUM);
+	spots += spots_avail.at(BUILDCAPS_BIG);
 
 	// checking amount of free spots, if needed setting new building stop flag
 	new_buildings_stop_ = false;
 
-	if (militarysites.size() * 2 + 20 < productionsites.size() or spots <
-	    (7 + static_cast<int32_t>(productionsites.size()) / 5)) {
+	if ((militarysites.size() * 2 + 20) <
+	    productionsites.size()
+	    or spots<(3 + (static_cast<int32_t>(productionsites.size()) / 5))or total_constructionsites>(
+	       (militarysites.size() + productionsites.size()) / 2)) {
 		new_buildings_stop_ = true;
 	}
 
 	if (kNewBuildingDebug)
-		log(" TDEBUG new buildings stop: %s; milit: %3" PRIuS " vs prod: %3" PRIuS
-		    " buildings, spots: %4d\n",
+		log(" TDEBUG new buildings stop: %s; milit: %3d vs prod: %3d buildings, spots: %4d\n",
 		    new_buildings_stop_ ? "Y" : "N",
 		    militarysites.size(),
 		    productionsites.size(),
@@ -903,9 +892,10 @@
 			    unstationed_milit_buildings_,
 			    military_under_constr_);
 	} else if (kMilitaryDebug)
-		log(" TDEBUG new military buildings stop OFF, %d %d\n",
+		log(" TDEBUG new military buildings stop OFF, %d %d, bf: %2d\n",
 		    unstationed_milit_buildings_,
-		    military_under_constr_);
+		    military_under_constr_,
+		    buildable_fields.size());
 
 	if (unstationed_milit_buildings_ + military_under_constr_ / 3 > 2 * treshold) {
 		near_enemy_b_buildings_stop = true;
@@ -928,11 +918,6 @@
 		military_boost = 200;
 	}
 
-	// Defensive AIs also attack sometimes (when they want to expand)
-	if (type == DEFENSIVE && expand_factor > 1)
-		if (next_attack_consideration_due_ <= game().get_gametime())
-			consider_attack(game().get_gametime());
-
 	// Building_Index proposed_building = INVALID_INDEX; // I need BuildingObserver not index
 	BuildingObserver* best_building = nullptr;
 	int32_t proposed_priority = 0;
@@ -996,7 +981,7 @@
 			if (bo.unoccupied_)
 				continue;
 
-			if (bo.type != BuildingObserver::MILITARYSITE and bo.cnt_under_construction_ >= 2)
+			if (not(bo.type == BuildingObserver::MILITARYSITE) and bo.cnt_under_construction_ >= 2)
 				continue;
 
 			// so we are going to seriously evaluate this building on this field,
@@ -1033,14 +1018,18 @@
 				}
 			}
 
+			int32_t prio = 0;  // score of a bulding on a field
+
 			// if current field is not big enough
 			if (bo.desc->get_size() > maxsize)
 				continue;
 
-			int32_t prio = 0;  // score of a bulding on a field
-
 			if (bo.type == BuildingObserver::PRODUCTIONSITE) {
 
+				// exclude spots on border
+				if (bf->near_border_ and not bo.need_trees_ and not bo.need_stones_)
+					continue;
+
 				// this can be only a well (as by now)
 				if (bo.mines_water_) {
 					if (bf->ground_water_ < 2)
@@ -1080,15 +1069,15 @@
 						    bo.cnt_built_,
 						    bo.cnt_under_construction_,
 						    bo.unoccupied_,
-						    bf->trees_nearby_ * 2,
+						    bf->trees_nearby_,
 						    (new_buildings_stop_) ? "Y" : "N");
 
 					if (bo.cnt_built_ + bo.cnt_under_construction_ + bo.unoccupied_ <= 2)
 						prio = bulgarian_constant + 200 + bf->trees_nearby_;
 					else if (bo.cnt_under_construction_ + bo.unoccupied_ <= 1) {
 						prio =
-						   bf->trees_nearby_ - 5 -
-						   new_buildings_stop_ * 40;  //+ bf->producers_nearby_.at(bo.outputs_.at(0))*5;
+						   bf->trees_nearby_ - 5 - bf->producers_nearby_.at(bo.outputs_.at(0)) * 5 -
+						   new_buildings_stop_ * 15;  //+ bf->producers_nearby_.at(bo.outputs_.at(0))*5;
 					}
 
 					if (kWoodDebug and prio > 0)
@@ -1114,10 +1103,10 @@
 						prio = prio * 2;
 
 					if (bo.total_count() == 0)
-						prio = prio * 2;
+						prio = prio * 5;
 
 					// to prevent to many quaries on one spot
-					prio = prio - 30 * bf->producers_nearby_.at(bo.outputs_.at(0));
+					prio = prio - 50 * bf->producers_nearby_.at(bo.outputs_.at(0));
 
 				} else if (bo.production_hint_ >= 0) {
 					// first setting targets (needed also for dismantling)
@@ -1128,33 +1117,58 @@
 						bo.cnt_target_ =
 						   1 + static_cast<int32_t>(mines_.size() + productionsites.size()) / 20;
 
-					if ((bo.cnt_under_construction_ + bo.unoccupied_) > 0)
+					if ((bo.cnt_under_construction_ + bo.unoccupied_) > 1)
 						continue;
 
 					// production hint (f.e. associate forester with logs)
 
-					if (bo.need_water_ and bf->water_nearby_ < 3)  // probably some of them needs water
+					if (bo.need_water_ and bf->water_nearby_ < 5)  // probably some of them needs water
 						continue;
 
 					if (bo.plants_trees_) {  // RANGERS
-						if (bo.total_count() < bo.cnt_target_)
-							prio = 70;
-						else {  // even when we are above goal we need to consider level of stock
-							if (bo.stocklevel_time < game().get_gametime() - 5 * 1000) {
-								bo.stocklevel_ =
-								   get_stocklevel_by_hint(static_cast<size_t>(bo.production_hint_));
-								bo.stocklevel_time = game().get_gametime();
-							}
-
-							if (bo.stocklevel_ < 5 and new_buildings_stop_)
-								prio = bf->producers_nearby_.at(bo.production_hint_) * 5 - 5 -
-								       bf->trees_nearby_ * 2;
-							else if (bo.stocklevel_ < 50)
-								prio = 50 + bf->producers_nearby_.at(bo.production_hint_) * 5 -
-								       bf->trees_nearby_ * 2;
-							else
-								continue;  // we are above tresh
+
+						// if there are too many trees nearby
+						if (bf->trees_nearby_ > 25 and bo.total_count() >= 2)
+							continue;
+
+						// sometimes all area is blocked by trees so this is to prevent this
+						if (buildable_fields.size() < 4)
+							continue;
+
+						// prevent too many rangers
+						if (bo.total_count() * 3 > static_cast<int32_t>(productionsites.size()))
+							continue;
+
+						if (bo.stocklevel_time < game().get_gametime() - 5 * 1000) {
+							bo.stocklevel_ =
+							   get_stocklevel_by_hint(static_cast<size_t>(bo.production_hint_));
+							bo.stocklevel_time = game().get_gametime();
 						}
+						prio = 0;
+						// if we need wood
+						if (bo.stocklevel_ < 50)
+							prio =
+							   (50 - bo.stocklevel_) + bf->producers_nearby_.at(bo.production_hint_) * 5;
+
+						// if we just need some rangers to be on safe side
+						if (bo.total_count() < 2)
+							prio += (60 - bf->trees_nearby_) * 3 +
+							        bf->producers_nearby_.at(bo.production_hint_) * 5;
+						else if (bo.total_count() < bo.cnt_target_)
+							prio += 30 + bf->producers_nearby_.at(bo.production_hint_) * 5;
+
+						if (kWoodDebug)
+							log(" RANGERS BUILT debug: goal: %2d, existing: %2d, cutters nearby: %2d, "
+							    "trees around: %2d, stocklevel: %2d\n",
+							    bo.cnt_target_,
+							    bo.total_count(),
+							    bf->producers_nearby_.at(bo.production_hint_),
+							    bf->trees_nearby_,
+							    bo.stocklevel_);
+
+						if (kWoodDebug)
+							log(" RANGERS BUILT debug: score: %2d \n", prio);
+
 					} else if (gametime > kBaseInfrastructureTime and not
 					                         new_buildings_stop_) {  // gamekeepers or so
 						if (bo.stocklevel_time < game().get_gametime() - 5 * 1000) {
@@ -1163,13 +1177,20 @@
 							bo.stocklevel_time = game().get_gametime();
 						}
 
+						// especially for fish breeders
+						if (bo.need_water_)
+							prio = bf->water_nearby_;
+
+						if (bo.total_count() == 0)
+							prio += 5;
+
 						if (bo.total_count() < bo.cnt_target_) {
-							prio = bf->producers_nearby_.at(bo.production_hint_) * 10;
-							prio = recalc_with_border_range(*bf, prio);
+							prio += bf->producers_nearby_.at(bo.production_hint_) * 10;
+							prio += recalc_with_border_range(*bf, prio);
 
 						} else if (bo.stocklevel_ < 50 and not new_buildings_stop_) {
-							prio = bf->producers_nearby_.at(bo.production_hint_) * 5;
-							prio = recalc_with_border_range(*bf, prio);  // only for not wood producers_
+							prio += bf->producers_nearby_.at(bo.production_hint_) * 5;
+							prio += recalc_with_border_range(*bf, prio);  // only for not wood producers_
 						} else
 							continue;
 					}
@@ -1203,17 +1224,29 @@
 					if ((bo.cnt_under_construction_ + bo.unoccupied_) > 0)
 						continue;
 
+					// if hunter and too little critters nearby skipping
+					if (bo.is_hunter_ and bf->critters_nearby_ < 5)
+						continue;
+					// similarly for fishers
+					if (bo.need_water_ and bf->fish_nearby_ <= 1)
+						continue;
+
 					// first eliminate buildings needing water if there is short supplies
-					if (bo.need_water_ and bf->water_nearby_ < 3)
+					if (bo.need_water_ and bf->water_nearby_ < 4)
 						continue;
 
-					if ((bo.is_basic_ or bo.prod_build_material_)and bo.total_count() == 0)
+					if (bo.is_basic_ and bo.total_count() == 0)
 						prio = 150 + max_preciousness;
-					else if (game().get_gametime() <
-					         kBaseInfrastructureTime or
-					            new_buildings_stop_)  // leave 15 minutes for basic infrastructure only
+					else if (bo.is_food_basic_ and game().get_gametime() >
+					            kPrimaryFoodStartTime and bo.total_count() ==
+					         0) {
+						// log (" %1d: Suggesting basic_food %12s\n",pn,bo.name);
+						prio = 40 + max_preciousness;
+					} else if (game().get_gametime() <
+					           kBaseInfrastructureTime or
+					              new_buildings_stop_)  // leave 15 minutes for basic infrastructure only
 						continue;
-					else if (((bo.is_basic_ or bo.prod_build_material_)and bo.total_count() <=
+					else if ((bo.is_basic_ and bo.total_count() <=
 					          1)or(output_is_needed and bo.total_count() == 0))
 						prio = 80 + max_preciousness;
 					else if (bo.inputs_.size() == 0) {
@@ -1221,8 +1254,9 @@
 						   1 + static_cast<int32_t>(mines_.size() + productionsites.size()) / 8;
 
 						if (bo.cnt_built_ >
-						    bo.cnt_target_ and not
-						       bo.space_consumer_)  // spaceconsumers_ can be built more then target
+						    bo.cnt_target_ and not(
+						       bo.space_consumer_ or bo.is_food_basic_))  // spaceconsumers_ and basic_s
+							                                               // can be built more then target
 							continue;
 
 						if (bo.stocklevel_time < game().get_gametime() - 5 * 1000) {
@@ -1238,8 +1272,8 @@
 						if (bo.stocklevel_ < 50) {
 							prio = max_preciousness + bulgarian_constant;
 
-							if (bo.space_consumer_)
-								prio += 5;
+							if (bo.space_consumer_)  // need to consider trees nearby
+								prio += 20 - (bf->trees_nearby_ / 3);
 
 							if (not bo.space_consumer_)
 								prio -= bf->producers_nearby_.at(bo.outputs_.at(0)) *
@@ -1250,8 +1284,27 @@
 
 							prio = recalc_with_border_range(*bf, prio);
 
+							if (bo.stocklevel_ < 20)
+								prio += 20 - bo.stocklevel_;
+
+							// fisher
+							if (bo.need_water_) {
+								prio += bf->fish_nearby_ - 4;
+								if (kHuntFishDebug)
+									log(" Proposing %12s, fishes around: %2d\n", bo.name, bf->fish_nearby_);
+							}
+
+							// hunters
+							if (bo.is_hunter_) {
+								prio += (bf->critters_nearby_ * 2) - 8;
+								if (kHuntFishDebug)
+									log(" Proposing %12s, critters*2-8 around: %2d\n",
+									    bo.name,
+									    bf->critters_nearby_);
+							}
+
 							if (kProductionDebug or(kSpaceDebug and bo.space_consumer_))
-								log(" TDEBUG: %1d: proposing %-15s , on stock: %3d(<50), stat: %3d, "
+								log(" TDEBUG: %1d: proposing %-15s , stocklevel: %3d(<50), stat: %3d, "
 								    "count: %2d/T:%2d, setting priority: %2d, on %3d %3d\n",
 								    player_number(),
 								    bo.name,
@@ -1266,10 +1319,9 @@
 					} else if (bo.inputs_.size() > 0) {
 						// to have two buildings from everything (intended for upgradeable buildings)
 						// but I do not know how to identify such buildings
-						if (bo.cnt_built_ == 1
-						    and game().get_gametime() > 60 * 60 * 1000
-						    and !bo.desc->enhancements().empty()
-						    and !mines_.empty()) {
+						if (bo.cnt_built_ == 1 and game().get_gametime() >
+						                        60 * 60 * 1000 and bo.desc->enhancements().size() >
+						                        0 and mines_.size() > 0) {
 							prio = max_preciousness + bulgarian_constant;
 						}
 						// if output is needed and there are no idle buildings
@@ -1319,6 +1371,7 @@
 				}
 			}  // production sites done
 			else if (bo.type == BuildingObserver::MILITARYSITE) {
+
 				if (military_boost > 1 and kMilitaryDebug)
 					log(" TDEBUG: boosting: unowned land %d \n", bf->unowned_land_nearby_);
 
@@ -1328,6 +1381,22 @@
 				if (near_enemy_b_buildings_stop and bf->enemy_nearby_)
 					continue;
 
+				if (bf->enemy_nearby_ and bo.fighting_type_)
+					;  // it is ok, go on
+				else if (bf->unowned_mines_pots_nearby_ >
+				         0 and(bo.mountain_conqueror_ or bo.expansion_type_))
+					;  // it is ok, go on
+				else if (bf->unowned_land_nearby_ and bo.expansion_type_) {
+					// decreasing probability for big buidlings
+					if (bo.desc->get_size() == 2 and gametime % 5 >= 1)
+						continue;
+					if (bo.desc->get_size() == 3 and gametime % 15 >= 1)
+						continue;
+				}
+				// it is ok, go on
+				else
+					continue;  // the building is not suitable for situation
+
 				if (bo.desc->get_size() ==
 				    3 and game().get_gametime() <
 				       15 * 60 * 1000)  // do not built fortresses in first half of hour of game
@@ -1337,7 +1406,7 @@
 					continue;
 
 				// not to build so many military buildings nearby
-				if (!bf->enemy_nearby_ and bf->military_in_constr_nearby_ > 1)
+				if (!bf->enemy_nearby_ and bf->military_in_constr_nearby_ > 0)
 					continue;
 
 				// here is to consider unowned potential mines
@@ -1387,6 +1456,11 @@
 				if (kMilitaryDebug and prio > 0)
 					log(" NEW MILITARY:  candidate's final priority: %d \n", prio);
 			} else if (bo.type == BuildingObserver::WAREHOUSE) {
+
+				// exclude spots on border
+				if (bf->near_border_)
+					continue;
+
 				//  Build one warehouse for ~every 35 productionsites and mines_.
 				//  Militarysites are slightly important as well, to have a bigger
 				//  chance for a warehouses (containing waiting soldiers or wares
@@ -1403,6 +1477,11 @@
 				// introduce check that there is no warehouse nearby to prevent to close placing
 
 			} else if (bo.type == BuildingObserver::TRAININGSITE) {
+
+				// exclude spots on border
+				if (bf->near_border_)
+					continue;
+
 				// build after 20 production sites and then after each 50 production site
 				if (static_cast<int32_t>((productionsites.size() + 30) / 50) >
 				       bo.total_count() and bo.cnt_under_construction_ ==
@@ -1439,7 +1518,7 @@
 		update_all_mineable_fields(gametime);
 		next_mine_construction_due_ = gametime + kIdleMineUpdateInterval;
 
-		if (!mineable_fields.empty()) {
+		if (mineable_fields.size() > 0) {
 
 			for (uint32_t i = 0; i < buildings.size() && productionsites.size() > 8; ++i) {
 				BuildingObserver& bo = buildings.at(i);
@@ -1566,6 +1645,7 @@
 		if (kWinnerDebug)
 			log(" TDEBUG:  no building picked up\n");
 
+		mine = false;
 		return false;
 	}
 
@@ -1575,15 +1655,27 @@
 	   game().map().get_fcoords(proposed_coords), game().get_gametime() + 120000);  // two minutes
 	blocked_fields.push_back(blocked);
 
-	if (best_building->type != BuildingObserver::MILITARYSITE)
+	// if space consumer we block also nearby fields
+	if (best_building->space_consumer_ and not best_building->plants_trees_) {
+		Map& map = game().map();
+
+		MapRegion<Area<FCoords>> mr(map, Area<FCoords>(map.get_fcoords(proposed_coords), 3));
+		do {
+			BlockedField blocked2(
+			   map.get_fcoords(*(mr.location().field)), game().get_gametime() + 45 * 60 * 1000);
+			blocked_fields.push_back(blocked2);
+		} while (mr.advance(map));
+	}
+
+	if (not(best_building->type == BuildingObserver::MILITARYSITE))
 		best_building->construction_decision_time_ = gametime;
 	else  // very ugly hack here
 		best_building->construction_decision_time_ = gametime - kBuildingMinInterval / 2;
 
 	if (kWinnerDebug)
-		log(" TDEBUG:  winning priority %4d, building %2d, coords: %3d x %3d, M: %s\n",
+		log(" TDEBUG:  winning priority %4d, building %16s, coords: %3d x %3d, Mine: %s\n",
 		    proposed_priority,
-		    best_building->id,
+		    best_building->name,
 		    proposed_coords.x,
 		    proposed_coords.y,
 		    mine ? "Y" : "N");
@@ -1686,7 +1778,7 @@
 	return false;
 }
 
-/// improves current road system
+// improves current road system
 bool DefaultAI::improve_roads(int32_t gametime) {
 	// Remove flags of dead end roads, as long as no more wares are stored on them
 	container_iterate(std::list<EconomyObserver*>, economies, i)
@@ -1819,7 +1911,7 @@
 	}
 }
 
-/// adds alternative ways to already existing ones
+// adds alternative ways to already existing ones
 bool DefaultAI::improve_transportation_ways(const Flag& flag) {
 	// First of all try to remove old building flags to clean up the road web if possible
 	container_iterate(std::list<Widelands::Coords>, flags_to_be_removed, i) {
@@ -1944,24 +2036,24 @@
 	if ((next_productionsite_check_due_ > gametime) || productionsites.empty())
 		return false;
 
-	next_productionsite_check_due_ = gametime + 5000;
+	next_productionsite_check_due_ = gametime + 4000;
 
-	// Get link to productionsite that should be checked
-	ProductionSiteObserver& productionsite_observer = productionsites.front();
+	bool changed = false;
+	// Reorder and set new values; - better now because there are multiple returns in the function
+	productionsites.push_back(productionsites.front());
 	productionsites.pop_front();
 
-	ProductionSite* productionsite = productionsite_observer.site.get(game());
-	if (!productionsite) {
-		// Site has vanished.
-		return false;
+	// Get link to productionsite that should be checked
+	ProductionSiteObserver& site = productionsites.front();
+
+	// first we werify if site is working yet (can be unoccupied since the start)
+	if (!site.site->can_start_working()) {
+		site.unoccupied_till_ = game().get_gametime();
 	}
-	// Push the back for future consideration.
-	productionsites.push_back(productionsite_observer);
 
-	bool changed = false;
 	// Get max radius of recursive workarea
 	Workarea_Info::size_type radius = 0;
-	const Workarea_Info& workarea_info = productionsite_observer.bo->desc->m_workarea_info;
+	const Workarea_Info& workarea_info = site.bo->desc->m_workarea_info;
 	container_iterate_const(Workarea_Info, workarea_info, i)
 
 	if (radius < i.current->first)
@@ -1971,43 +2063,43 @@
 
 	// do not dismantle same type of building too soon - to give some time to update statistics
 	// yes it interferes with building updates, but not big problem here
-	if (productionsite_observer.bo->last_dismantle_time_ > game().get_gametime() - 30 * 1000)
+	if (site.bo->last_dismantle_time_ > game().get_gametime() - 30 * 1000)
 		return false;
 
 	// Lumberjack / Woodcutter handling
-	if (productionsite_observer.bo->need_trees_) {
-		if (map.find_immovables(
-		       Area<FCoords>(map.get_fcoords(productionsite->get_position()), radius),
-		       nullptr,
-		       FindImmovableAttribute(Map_Object_Descr::get_attribute_id("tree"))) < 6) {
+	if (site.bo->need_trees_) {
+		if (map.find_immovables(Area<FCoords>(map.get_fcoords(site.site->get_position()), radius),
+		                        nullptr,
+		                        FindImmovableAttribute(Map_Object_Descr::get_attribute_id("tree"))) <
+		    6) {
 			// Do not destruct the last lumberjack - perhaps some small trees are
 			// near, a forester will plant some trees or some new trees will seed
 			// in reach. Computer player_s can easily run out of wood if this check
 			// is not done.
-			if (productionsite_observer.bo->cnt_built_ <=
+			if (site.bo->cnt_built_ <=
 			    3 + static_cast<int32_t>(mines_.size() + productionsites.size()) / 20) {
 				if (kWoodDebug)
 					log(" TDEBUG: %1d: cutter without trees, but not dismantling due to low numbers of "
 					    "cutters (%2d)\n",
 					    player_number(),
-					    productionsite_observer.bo->cnt_built_);
+					    site.bo->cnt_built_);
 
 				return false;
 			}
 
-			if (productionsite->get_statistics_percent() <= 20) {
+			if (site.site->get_statistics_percent() <= 20) {
 				// destruct the building and it's flag (via flag destruction)
 				// the destruction of the flag avoids that defaultAI will have too many
 				// unused roads - if needed the road will be rebuild directly.
 				// log (" TDEBUG: dismantling lumberjacks hut\n");
-				productionsite_observer.bo->last_dismantle_time_ = game().get_gametime();
-				flags_to_be_removed.push_back(productionsite->base_flag().get_position());
-				game().send_player_dismantle(*productionsite);
+				site.bo->last_dismantle_time_ = game().get_gametime();
+				flags_to_be_removed.push_back(site.site->base_flag().get_position());
+				game().send_player_dismantle(*site.site);
 
 				if (kWoodDebug)
 					log(" TDEBUG %1d: cutter without trees, dismantling..., remaining cutters: %2d\n",
 					    player_number(),
-					    productionsite_observer.bo->cnt_built_);
+					    site.bo->cnt_built_);
 
 				return true;
 			}
@@ -2017,16 +2109,16 @@
 	}
 
 	// Wells handling
-	if (productionsite_observer.bo->mines_water_) {
-		if (productionsite_observer.built_time_ + 6 * 60 * 1000 <
-		       game().get_gametime() and productionsite->get_statistics_percent() ==
+	if (site.bo->mines_water_) {
+		if (site.unoccupied_till_ + 6 * 60 * 1000 < game().get_gametime()
+		                                            and site.site->get_statistics_percent() ==
 		    0) {
 			if (kWellDebug)
 				log(" TDEBUG: dismantling Well, statistics: %3d,\n",
-				    productionsite->get_statistics_percent());
-			productionsite_observer.bo->last_dismantle_time_ = game().get_gametime();
-			flags_to_be_removed.push_back(productionsite->base_flag().get_position());
-			game().send_player_dismantle(*productionsite);
+				    site.site->get_statistics_percent());
+			site.bo->last_dismantle_time_ = game().get_gametime();
+			flags_to_be_removed.push_back(site.site->base_flag().get_position());
+			game().send_player_dismantle(*site.site);
 
 			return true;
 		}
@@ -2034,39 +2126,39 @@
 	}
 
 	// Quarry handling
-	if (productionsite_observer.bo->need_stones_) {
+	if (site.bo->need_stones_) {
 		if (kQuarryDismDebug) {
 			log(" QUARRY at %3d x %3d: statistics: %3d/%3d, age: %5d(>360s), stones:%3d\n",
-			    productionsite->get_position().x,
-			    productionsite->get_position().y,
-			    productionsite->get_statistics_percent(),
-			    productionsite->get_crude_statistics(),
-			    (gametime - productionsite_observer.built_time_) / 1000,
+			    site.site->get_position().x,
+			    site.site->get_position().y,
+			    site.site->get_statistics_percent(),
+			    site.site->get_crude_statistics(),
+			    (gametime - site.unoccupied_till_) / 1000,
 			    map.find_immovables(
-			       Area<FCoords>(map.get_fcoords(productionsite->get_position()), radius),
+			       Area<FCoords>(map.get_fcoords(site.site->get_position()), radius),
 			       nullptr,
 			       FindImmovableAttribute(Map_Object_Descr::get_attribute_id("stone"))));
 		}
 
 		if (map.find_immovables(
-		       Area<FCoords>(map.get_fcoords(productionsite->get_position()), radius),
+		       Area<FCoords>(map.get_fcoords(site.site->get_position()), radius),
 		       nullptr,
 		       FindImmovableAttribute(Map_Object_Descr::get_attribute_id("stone"))) == 0) {
 			// destruct the building and it's flag (via flag destruction)
 			// the destruction of the flag avoids that defaultAI will have too many
 			// unused roads - if needed the road will be rebuild directly.
-			flags_to_be_removed.push_back(productionsite->base_flag().get_position());
-			game().send_player_dismantle(*productionsite);
+			flags_to_be_removed.push_back(site.site->base_flag().get_position());
+			game().send_player_dismantle(*site.site);
 			return true;
 		}
 
-		if (productionsite_observer.built_time_ + 6 * 60 * 1000 <
-		       game().get_gametime() and productionsite->get_statistics_percent() ==
+		if (site.unoccupied_till_ + 6 * 60 * 1000 < game().get_gametime()
+		                                            and site.site->get_statistics_percent() ==
 		    0) {
 			// it is possible that there are stones but quary is not able to mine them
-			productionsite_observer.bo->last_dismantle_time_ = game().get_gametime();
-			flags_to_be_removed.push_back(productionsite->base_flag().get_position());
-			game().send_player_dismantle(*productionsite);
+			site.bo->last_dismantle_time_ = game().get_gametime();
+			flags_to_be_removed.push_back(site.site->base_flag().get_position());
+			game().send_player_dismantle(*site.site);
 
 			return true;
 		}
@@ -2075,57 +2167,58 @@
 	}
 
 	// All other SPACE_CONSUMERS without input and above target_count
-	if (kSpaceDebug and productionsite_observer.bo->space_consumer_ and not
-	       productionsite_observer.bo->plants_trees_)
+	if (kSpaceDebug and site.bo->space_consumer_ and not site.bo->plants_trees_)
 		log(" TDEBUG: space consumer here: %15s at %3d x %3d: statistics: %3d, age: %5d(>360s)\n",
-		    productionsite_observer.bo->name,
-		    productionsite->get_position().x,
-		    productionsite->get_position().y,
-		    productionsite->get_statistics_percent(),
-		    (gametime - productionsite_observer.built_time_) / 1000);
+		    site.bo->name,
+		    site.site->get_position().x,
+		    site.site->get_position().y,
+		    site.site->get_statistics_percent(),
+		    (gametime - site.unoccupied_till_) / 1000);
 
-	if (productionsite_observer.bo->inputs_.empty()  // does not consume anything
-	    and productionsite_observer.bo->production_hint_ ==
+	if (site.bo->inputs_.empty()  // does not consume anything
+	    and site.bo->production_hint_ ==
 	    -1  // not a renewing building (forester...)
-	          and productionsite_observer.built_time_ +
-	          6 * 60 * 1000 <
-	       game().get_gametime()                    // > 10 minutes old
-	       and productionsite->can_start_working()  // building is occupied
-	       and productionsite_observer.bo->space_consumer_ and not
-	          productionsite_observer.bo->plants_trees_) {
-		if (productionsite_observer.bo->cnt_built_ > productionsite_observer.bo->cnt_target_) {
-			if (productionsite_observer.bo->stocklevel_time < game().get_gametime() - 5 * 1000) {
-				productionsite_observer.bo->stocklevel_ = get_stocklevel(*productionsite_observer.bo);
-				productionsite_observer.bo->stocklevel_time = game().get_gametime();
+	          and site.unoccupied_till_ +
+	          10 * 60 * 1000 <
+	       game().get_gametime()               // > 10 minutes old
+	       and site.site->can_start_working()  // building is occupied
+	       and site.bo->space_consumer_ and not site.bo->plants_trees_) {
+
+		// if we have more buildings then target
+		if (site.bo->cnt_built_ > site.bo->cnt_target_) {
+			if (site.bo->stocklevel_time < game().get_gametime() - 5 * 1000) {
+				site.bo->stocklevel_ = get_stocklevel(*site.bo);
+				site.bo->stocklevel_time = game().get_gametime();
 			}
 
 			if (kSpaceDebug)
 				log(" TDEBUG: considering dismantle of space consumer: %15s, count %2d/T:%2d, stock "
 				    "level:%3d(>100)\n",
-				    productionsite_observer.bo->name,
-				    productionsite_observer.bo->cnt_built_,
-				    productionsite_observer.bo->cnt_target_,
-				    productionsite_observer.bo->stocklevel_);
+				    site.bo->name,
+				    site.bo->cnt_built_,
+				    site.bo->cnt_target_,
+				    site.bo->stocklevel_);
 
-			if (productionsite->get_statistics_percent()<
-			       95 and productionsite_observer.bo->stocklevel_> 100) {  // production stats == 0%
-				productionsite_observer.bo->last_dismantle_time_ = game().get_gametime();
-				flags_to_be_removed.push_back(productionsite->base_flag().get_position());
-				game().send_player_dismantle(*productionsite);
+			if (site.site->get_statistics_percent()<
+			       30 and site.bo->stocklevel_> 100) {  // production stats == 0%
+				site.bo->last_dismantle_time_ = game().get_gametime();
+				flags_to_be_removed.push_back(site.site->base_flag().get_position());
+				game().send_player_dismantle(*site.site);
 				return true;
 			}
 		}
 
-		if (productionsite->get_statistics_percent() <= 20) {
+		// regardless of count of sites a building can be dismanteld if it performs too bad
+		if (site.site->get_statistics_percent() <= 10) {
 			if (kSpaceDebug)
 				log(" TDEBUG: dismantling: %15s at %3d x %3d: due to low performance: %2d\n",
-				    productionsite_observer.bo->name,
-				    productionsite->get_position().x,
-				    productionsite->get_position().y,
-				    productionsite->get_statistics_percent());
+				    site.bo->name,
+				    site.site->get_position().x,
+				    site.site->get_position().y,
+				    site.site->get_statistics_percent());
 
-			flags_to_be_removed.push_back(productionsite->base_flag().get_position());
-			game().send_player_dismantle(*productionsite);
+			flags_to_be_removed.push_back(site.site->base_flag().get_position());
+			game().send_player_dismantle(*site.site);
 			return true;
 		}
 
@@ -2133,61 +2226,104 @@
 	}
 
 	// buildings with inputs_, checking if we can a dismantle some due to low performance
-	if (productionsite_observer.bo->inputs_.size() > 0 and productionsite_observer.bo->cnt_built_ >=
-	    3 and productionsite_observer.bo->current_stats_ < 30) {
+	if (site.bo->inputs_.size() > 0 and(site.bo->cnt_built_ - site.bo->unoccupied_) >=
+	    3 and site.site->can_start_working() and site.site->get_statistics_percent() <
+	    20 and                             // statistics for the building
+	       site.bo->current_stats_<30 and  // overall statistics
+	                               (game().get_gametime() - site.unoccupied_till_)> 10 *
+	       60 * 1000) {
 		if (kIdleDismantle)
 			log(" kIdleDismantle: dismantling due to too many buildings: %15s at %3d x %3d, total "
-			    "counts: %2d, stat: %2d\n",
-			    productionsite_observer.bo->name,
-			    productionsite->get_position().x,
-			    productionsite->get_position().y,
-			    productionsite_observer.bo->cnt_built_,
-			    productionsite_observer.bo->current_stats_);
-		productionsite_observer.bo->last_dismantle_time_ = game().get_gametime();
-		flags_to_be_removed.push_back(productionsite->base_flag().get_position());
-		game().send_player_dismantle(*productionsite);
+			    "count: %2d, stat: %2d/%3d\n",
+			    site.bo->name,
+			    site.site->get_position().x,
+			    site.site->get_position().y,
+			    site.bo->cnt_built_,
+			    site.site->get_statistics_percent(),
+			    site.bo->current_stats_);
+		site.bo->last_dismantle_time_ = game().get_gametime();
+		flags_to_be_removed.push_back(site.site->base_flag().get_position());
+		game().send_player_dismantle(*site.site);
+		return true;
+	}
+
+	// remaining buildings without inputs and not supporting ones (fishers only left probably and
+	// huters)
+	// first if is only for log, second one is "executive"
+	if (kHuntFishDebug and site.bo->inputs_.size() ==
+	    0 and site.site->can_start_working() and not site.bo->space_consumer_ and
+	          site.bo->production_hint_ < 0 and site.site->get_statistics_percent() <
+	       50 and((game().get_gametime() - site.unoccupied_till_) > 5 * 60 * 1000)) {
+		if (kIdleDismantle)
+			log(" kIdleDismantle: Fisher+Hunters: considering dismantle due to too low "
+			    "utilization: %15s at %3d x %3d, total "
+			    " stat: %2d, age: %4d\n",
+			    site.bo->name,
+			    site.site->get_position().x,
+			    site.site->get_position().y,
+			    site.site->get_statistics_percent(),
+			    (game().get_gametime() - site.unoccupied_till_) / 1000 / 60);
+	}
+	if (site.bo->inputs_.size() ==
+	    0 and site.bo->production_hint_ <
+	       0 and site.site->can_start_working()
+	       and not site.bo->space_consumer_ and site.site->get_statistics_percent() <
+	       10 and((game().get_gametime() - site.built_time_) > 10 * 60 * 1000)) {
+		if (kIdleDismantle)
+			log(" kIdleDismantle: dismantling due to too low utilization: %15s at %3d x %3d, total "
+			    " stat: %2d, age: %4d\n",
+			    site.bo->name,
+			    site.site->get_position().x,
+			    site.site->get_position().y,
+			    site.site->get_statistics_percent(),
+			    (game().get_gametime() - site.built_time_) / 1000 / 60);
+		site.bo->last_dismantle_time_ = game().get_gametime();
+		flags_to_be_removed.push_back(site.site->base_flag().get_position());
+		game().send_player_dismantle(*site.site);
 		return true;
 	}
 
 	// supporting productionsites (rangers)
 	// stop/start them based on stock avaiable
-	if (productionsite_observer.bo->production_hint_ >= 0) {
-		if (productionsite_observer.bo->stocklevel_time < game().get_gametime() - 5 * 1000) {
-			productionsite_observer.bo->stocklevel_ =
-			   get_stocklevel_by_hint(productionsite_observer.bo->production_hint_);
-			productionsite_observer.bo->stocklevel_time = game().get_gametime();
+	if (site.bo->production_hint_ >= 0) {
+		// if (kStandbyDebug) log ("  TDEBUG: check_productionsites(): testing building
+		// %s\n",site.bo->name);
+		if (site.bo->stocklevel_time < game().get_gametime() - 5 * 1000) {
+			site.bo->stocklevel_ = get_stocklevel_by_hint(site.bo->production_hint_);
+			site.bo->stocklevel_time = game().get_gametime();
 		}
 
+		uint16_t score = site.bo->stocklevel_;
+
 		if (kStandbyDebug)
 			log("  TDEBUG: standby review: %-16s(%dx):stock level: %3d, status: %s\n",
-			    productionsite_observer.bo->name,
-			    productionsite_observer.bo->cnt_built_,
-			    productionsite_observer.bo->stocklevel_,
-			    productionsite->is_stopped() ? "stopped" : "running");
+			    site.bo->name,
+			    site.bo->cnt_built_,
+			    site.bo->stocklevel_,
+			    site.site->is_stopped() ? "stopped" : "running");
 
-		if (productionsite_observer.bo->stocklevel_ > 200 and productionsite_observer.bo->cnt_built_ >
-		    productionsite_observer.bo->cnt_target_) {
+		if (score > 150 and site.bo->cnt_built_ > site.bo->cnt_target_) {
 			if (kStandbyDebug)
 				log("   * dismantling the building\n");
 
-			productionsite_observer.bo->last_dismantle_time_ = game().get_gametime();
-			flags_to_be_removed.push_back(productionsite->base_flag().get_position());
-			game().send_player_dismantle(*productionsite);
+			site.bo->last_dismantle_time_ = game().get_gametime();
+			flags_to_be_removed.push_back(site.site->base_flag().get_position());
+			game().send_player_dismantle(*site.site);
 			return true;
 		}
 
-		if (productionsite_observer.bo->stocklevel_ > 150 and not productionsite->is_stopped()) {
+		if (score > 70 and not site.site->is_stopped()) {
 			if (kStandbyDebug)
 				log("   * stopping building\n");
 
-			game().send_player_start_stop_building(*productionsite);
+			game().send_player_start_stop_building(*site.site);
 		}
 
-		if (productionsite_observer.bo->stocklevel_ < 100 and productionsite->is_stopped()) {
+		if (score < 50 and site.site->is_stopped()) {
 			if (kStandbyDebug)
 				log("   * starting building\n");
 
-			game().send_player_start_stop_building(*productionsite);
+			game().send_player_start_stop_building(*site.site);
 		}
 	}
 
@@ -2197,14 +2333,14 @@
 	// statistics percents are decisive
 
 	// do not upgrade if current building is only one in operation
-	if ((productionsite_observer.bo->cnt_built_ - productionsite_observer.bo->unoccupied_) <= 1)
+	if ((site.bo->cnt_built_ - site.bo->unoccupied_) <= 1)
 		return false;
 
 	// Check whether building is enhanceable and if wares of the enhanced
 	// buildings are needed. If yes consider an upgrade.
-	std::set<Building_Index> enhancements = productionsite->enhancements();
+	std::set<Building_Index> enhancements = site.site->enhancements();
 	int32_t maxprio = 0;
-	Building_Index enbld = INVALID_INDEX;
+	Building_Index enbld;  // to get rid of this
 	BuildingObserver* bestbld = nullptr;
 	container_iterate_const(std::set<Building_Index>, enhancements, x) {
 		// Only enhance buildings that are allowed (scenario mode)
@@ -2222,23 +2358,22 @@
 				continue;
 
 			// don't upgrade without workers
-			if (!productionsite->has_workers(*x.current, game()))
+			if (!site.site->has_workers(*x.current, game()))
 				continue;
 
 			// forcing first upgrade
-			if ((en_bo.cnt_under_construction_ + en_bo.cnt_built_ + en_bo.unoccupied_) == 0
-			    and (productionsite_observer.bo->cnt_built_ -
-			          productionsite_observer.bo->unoccupied_) >= 1
-			    and (game().get_gametime() - productionsite_observer.built_time_) > 30 * 60 * 1000
-			    and !mines_.empty()) {
+			if ((en_bo.cnt_under_construction_ + en_bo.cnt_built_ + en_bo.unoccupied_) ==
+			    0 and(site.bo->cnt_built_ - site.bo->unoccupied_) >=
+			       1 and(game().get_gametime() - site.unoccupied_till_) >
+			       30 * 60 * 1000 and mines_.size() > 0) {
 				if (kUpgradeDebug)
 					log(" UPGRADE: upgrading (forcing as first) %12s at %3d x %3d: age %d min.\n",
-					    productionsite_observer.bo->name,
-					    productionsite->get_position().x,
-					    productionsite->get_position().y,
-					    (game().get_gametime() - productionsite_observer.built_time_) / 60000);
+					    site.bo->name,
+					    site.site->get_position().x,
+					    site.site->get_position().y,
+					    (game().get_gametime() - site.unoccupied_till_) / 60000);
 
-				game().send_player_enhance_building(*productionsite, (*x.current));
+				game().send_player_enhance_building(*site.site, (*x.current));
 				return true;
 			}
 
@@ -2260,16 +2395,15 @@
 			int32_t prio = 0;
 
 			if (en_bo.current_stats_ > 65) {
-				prio = en_bo.current_stats_ -
-				       productionsite_observer.bo->current_stats_;  // priority for enhancement
+				prio = en_bo.current_stats_ - site.bo->current_stats_;  // priority for enhancement
 				prio += en_bo.current_stats_ - 65;
 
 				if (kUpgradeDebug)
 					log(" UPGRADE:  proposing upgrade (non-first building) %12s at %3d x %3d: prio: "
 					    "%2d, target statistics: %2d\n",
-					    productionsite_observer.bo->name,
-					    productionsite->get_position().x,
-					    productionsite->get_position().y,
+					    site.bo->name,
+					    site.site->get_position().x,
+					    site.site->get_position().y,
 					    prio,
 					    en_bo.current_stats_);
 			}
@@ -2288,7 +2422,7 @@
 		if (kUpgradeDebug)
 			log(" UPGRADE:   upgrading %15s(as non first)\n", bestbld->name);
 
-		game().send_player_enhance_building(*productionsite, enbld);
+		game().send_player_enhance_building(*site.site, enbld);
 		bestbld->construction_decision_time_ = gametime;
 		changed = true;
 	}
@@ -2307,34 +2441,40 @@
 		return false;
 
 	next_mine_check_due_ = gametime + 10000;  // 10 seconds is enough
+	// Reorder and set new values; - due to returns within the function
+	mines_.push_back(mines_.front());
+	mines_.pop_front();
 	// also statistics must be recalculated
 	// Get link to productionsite that should be checked
-	ProductionSiteObserver& productionsite_observer = mines_.front();
-	mines_.pop_front();
-
-	ProductionSite* mine = productionsite_observer.site.get(game());
-	if (!mine) {
-		// Building has vanished.
-		return false;
-	}
-
+	ProductionSiteObserver& site = mines_.front();
 	Map& map = game().map();
-	Field* field = map.get_fcoords(mine->get_position()).field;
-	// Reorder and set new values; - due to returns within the function
-	mines_.push_back(productionsite_observer);
+	Field* field = map.get_fcoords(site.site->get_position()).field;
 
 	if (kMinesUpdateDebug)
 		log(" MINES_UPDATE: %1d: reviewing %-15s at %3dx%3d, statistics: %3d, left resources: %2d\n",
 		    player_number(),
-		    productionsite_observer.bo->name,
-		    mine->get_position().x,
-		    mine->get_position().y,
-		    mine->get_statistics_percent(),
+		    site.bo->name,
+		    site.site->get_position().x,
+		    site.site->get_position().y,
+		    site.site->get_statistics_percent(),
 		    field->get_resources_amount());
 
+	// first get rid of mines that are missing workers for some time (5 minutes)
+	// released worker (if any) can be usefull elsewhere !
+	if (site.built_time_ + 5 * 60 * 1000 < gametime and not site.site->can_start_working()) {
+		if (kMinesUpdateDebug)
+			log(" MINES_UPDATE: Dismantling due to missing workers: %12s at %3d %3d\n",
+			    site.bo->name,
+			    site.site->get_position().x,
+			    site.site->get_position().y);
+		flags_to_be_removed.push_back(site.site->base_flag().get_position());
+		game().send_player_dismantle(*site.site);
+		return true;
+	}
+
 	// It takes some time till performance gets to 0
 	// so I use 40% as a limit to check if there are some resources left
-	if (mine->get_statistics_percent() > 40)
+	if (site.site->get_statistics_percent() > 40)
 		return false;
 
 	// Check if mine ran out of resources
@@ -2344,8 +2484,8 @@
 		// destruct the building and it's flag (via flag destruction)
 		// the destruction of the flag avoids that defaultAI will have too many
 		// unused roads - if needed the road will be rebuild directly.
-		flags_to_be_removed.push_back(mine->base_flag().get_position());
-		game().send_player_dismantle(*mine);
+		flags_to_be_removed.push_back(site.site->base_flag().get_position());
+		game().send_player_dismantle(*site.site);
 
 		if (kMinesUpdateDebug)
 			log(" MINES_UPDATE: Dismantling...\n");
@@ -2354,9 +2494,9 @@
 	}
 
 	// Check whether building is enhanceable. If yes consider an upgrade.
-	std::set<Building_Index> enhancements = mine->enhancements();
+	std::set<Building_Index> enhancements = site.site->enhancements();
 	int32_t maxprio = 0;
-	Building_Index enbld = INVALID_INDEX;
+	Building_Index enbld;
 	BuildingObserver* bestbld = nullptr;
 	bool changed = false;
 	container_iterate_const(std::set<Building_Index>, enhancements, x) {
@@ -2387,8 +2527,8 @@
 				continue;
 
 			// Check if mine needs an enhancement to mine more resources
-			uint8_t const until = field->get_starting_res_amount() *
-			                      (100 - productionsite_observer.bo->mines_percent_) / 100;
+			uint8_t const until =
+			   field->get_starting_res_amount() * (100 - site.bo->mines_percent_) / 100;
 
 			if (kMinesUpdateDebug)
 				log(" MINES_UPDATE:    until:%3d ?>, current: %3d\n", until, current);
@@ -2412,7 +2552,7 @@
 
 	// Enhance if enhanced building is useful
 	if (maxprio > 0) {
-		game().send_player_enhance_building(*mine, enbld);
+		game().send_player_enhance_building(*site.site, enbld);
 		bestbld->construction_decision_time_ = gametime;
 		changed = true;
 
@@ -2420,9 +2560,6 @@
 			log(" MINES_UPDATE:    ..enhancing\n");
 	}
 
-	//// Reorder and set new values;
-	// mines_.push_back(mines_.front());
-	// mines_.pop_front();
 	return changed;
 }
 
@@ -2439,7 +2576,7 @@
 	}
 
 	if (kStockDebug)
-		log(" TDEBUG: stock : %3u for hint: %2" PRIuS ", time: %3d\n",
+		log(" TDEBUG: stock : %3d for hint: %2d, time: %3d\n",
 		    count,
 		    hintoutput,
 		    game().get_gametime() / 1000);
@@ -2518,10 +2655,12 @@
 	uint32_t const vision = ms->vision_range();
 	FCoords f = map.get_fcoords(ms->get_position());
 	// look if there is any enemy land nearby
-	FindNodeEnemy find_enemy(player, game());
+	// FindNodeEnemy find_enemy(player, game());
+	// look if there is any enemies building
+	FindNodeEnemiesBuilding find_enemy(player, game());
 
-	// first if there are enemies nearby
-	if (map.find_fields(Area<FCoords>(f, vision), nullptr, find_enemy) == 0) {
+	// first if there are enemies nearby, check for buildings not land
+	if (map.find_fields(Area<FCoords>(f, vision + 2), nullptr, find_enemy) == 0) {
 		// If no enemy in sight - decrease the number of stationed soldiers
 		// as long as it is > 1 - BUT take care that there is a warehouse in the
 		// same economy where the thrown out soldiers can go to.
@@ -2579,10 +2718,11 @@
 		uint32_t const k = ms->soldierCapacity();
 
 		if (j > k)
-			game().send_player_change_soldier_capacity(*ms, j - k);
+			// game().send_player_change_soldier_capacity(*ms, j - k);
 
-		if (MilitarySite::kPrefersHeroes != ms->get_soldier_preference())
-			game().send_player_militarysite_set_soldier_preference(*ms, MilitarySite::kPrefersHeroes);
+			if (MilitarySite::kPrefersHeroes != ms->get_soldier_preference())
+				game().send_player_militarysite_set_soldier_preference(
+				   *ms, MilitarySite::kPrefersHeroes);
 
 		changed = true;
 	}
@@ -2606,7 +2746,7 @@
  */
 int32_t DefaultAI::recalc_with_border_range(const BuildableField& bf, int32_t prio) {
 	// Prefer building space in the inner land.
-	prio /= (1 + (bf.unowned_land_nearby_ / 4));
+	// prio /= (1 + (bf.unowned_land_nearby_ / 4));
 
 	if (bf.unowned_land_nearby_ > 15)
 		prio -= (bf.unowned_land_nearby_ - 15);
@@ -2700,7 +2840,7 @@
 	return economies.front();
 }
 
-/// \returns the building observer
+// \returns the building observer
 BuildingObserver& DefaultAI::get_building_observer(char const* const name) {
 	if (tribe == nullptr)
 		late_initialization();
@@ -2712,7 +2852,7 @@
 	throw wexception("Help: I do not know what to do with a %s", name);
 }
 
-/// this is called whenever we gain ownership of a PlayerImmovable
+// this is called whenever we gain ownership of a PlayerImmovable
 void DefaultAI::gain_immovable(PlayerImmovable& pi) {
 	if (upcast(Building, building, &pi))
 		gain_building(*building);
@@ -2722,7 +2862,7 @@
 		roads.push_front(road);
 }
 
-/// this is called whenever we lose ownership of a PlayerImmovable
+// this is called whenever we lose ownership of a PlayerImmovable
 void DefaultAI::lose_immovable(const PlayerImmovable& pi) {
 	if (upcast(Building const, building, &pi))
 		lose_building(*building);
@@ -2745,7 +2885,7 @@
 		roads.remove(road);
 }
 
-/// this is called whenever we gain a new building
+// this is called whenever we gain a new building
 void DefaultAI::gain_building(Building& b) {
 	BuildingObserver& bo = get_building_observer(b.name().c_str());
 
@@ -2764,6 +2904,7 @@
 			productionsites.back().site = &ref_cast<ProductionSite, Building>(b);
 			productionsites.back().bo = &bo;
 			productionsites.back().built_time_ = game().get_gametime();
+			productionsites.back().unoccupied_till_ = game().get_gametime();
 			productionsites.back().stats_zero_ = 0;
 
 			for (uint32_t i = 0; i < bo.outputs_.size(); ++i)
@@ -2775,6 +2916,7 @@
 			mines_.push_back(ProductionSiteObserver());
 			mines_.back().site = &ref_cast<ProductionSite, Building>(b);
 			mines_.back().bo = &bo;
+			mines_.back().built_time_ = game().get_gametime();
 
 			for (uint32_t i = 0; i < bo.outputs_.size(); ++i)
 				++wares.at(bo.outputs_.at(i)).producers_;
@@ -2786,16 +2928,18 @@
 			militarysites.back().site = &ref_cast<MilitarySite, Building>(b);
 			militarysites.back().bo = &bo;
 			militarysites.back().checks = bo.desc->get_size();
+			militarysites.back().enemies_nearby = true;
 		} else if (bo.type == BuildingObserver::WAREHOUSE)
 			++numof_warehouses_;
 	}
 }
 
-/// this is called whenever we lose a building
+// this is called whenever we lose a building
 void DefaultAI::lose_building(const Building& b) {
 	BuildingObserver& bo = get_building_observer(b.name().c_str());
 
 	if (bo.type == BuildingObserver::CONSTRUCTIONSITE) {
+		// log (" TDEBUG: We lost constructionsite\n");
 		BuildingObserver& target_bo = get_building_observer(
 		   ref_cast<ConstructionSite const, Building const>(b).building().name().c_str());
 		--target_bo.cnt_under_construction_;
@@ -2804,10 +2948,13 @@
 		--bo.cnt_built_;
 
 		if (bo.type == BuildingObserver::PRODUCTIONSITE) {
+
+			// log (" TDEBUG: We lost productionsite: %s\n",b.name().c_str());
+
 			for (std::list<ProductionSiteObserver>::iterator i = productionsites.begin();
 			     i != productionsites.end();
 			     ++i)
-				if (i->site.get(game()) == &b) {
+				if (i->site == &b) {
 					productionsites.erase(i);
 					break;
 				}
@@ -2820,7 +2967,7 @@
 		} else if (bo.type == BuildingObserver::MINE) {
 			for (std::list<ProductionSiteObserver>::iterator i = mines_.begin(); i != mines_.end();
 			     ++i)
-				if (i->site.get(game()) == &b) {
+				if (i->site == &b) {
 					mines_.erase(i);
 					break;
 				}
@@ -2848,8 +2995,8 @@
 	m_mineable_changed = true;
 }
 
-/// Checks that supply line exists for given building.
-/// Recurcsively verify that all inputs_ have a producer.
+// Checks that supply line exists for given building.
+// Recurcsively verify that all inputs_ have a producer.
 // TODO: this function leads to periodic freezes of ~1 second on big games on my system.
 // TODO: It needs profiling and optimization.
 // NOTE: This is not needed anymore and it seems it is not missed neither
@@ -2881,76 +3028,226 @@
 	if (militarysites.empty())
 		return false;
 
-	Map& map = game().map();
+	// First we iterate over all players and define which ones (if any)
+	// are attackable (comparing overal strength)
+	// counting players in game
+	uint32_t plr_in_game = 0;
+	std::vector<bool> player_attackable;
+	Player_Number const nr_players = game().map().get_nrplayers();
+	player_attackable.resize(nr_players);
+	bool any_attackable = false;
+	bool any_attacked = false;
 	uint16_t const pn = player_number();
-	// Check next militarysite
-	MilitarySite* ms = militarysites.front().site;
-	uint32_t const vision = ms->vision_range();
-	FCoords f = map.get_fcoords(ms->get_position());
-	Building* target = ms;  // dummy initialisation to silence the compiler
-	int32_t chance = 0;
-	uint32_t attackers = 0;
-	// Search in a radius of the vision of the militarysite and collect
-	// information about immovables in the area
-	std::vector<ImmovableFound> immovables;
-	map.find_immovables(Area<FCoords>(f, vision), &immovables, FindImmovableAttackable());
-
-	for (uint32_t j = 0; j < immovables.size(); ++j)
-		if (upcast(MilitarySite, bld, immovables.at(j).object)) {
-			if (!player->is_hostile(bld->owner()))
-				continue;
-
-			if (bld->canAttack()) {
-				int32_t ta = player->findAttackSoldiers(bld->base_flag());
-
-				if (type == NORMAL)
-					ta = ta * 2 / 3;
-
-				if (ta < 1)
-					continue;
-
-				int32_t const tc = ta - bld->presentSoldiers().size();
-
-				if (tc > chance) {
-					target = bld;
-					chance = tc;
-					attackers = ta;
-				}
-			}
-		} else if (upcast(Warehouse, wh, immovables.at(j).object)) {
-			if (!player->is_hostile(wh->owner()))
-				continue;
-
-			if (wh->canAttack()) {
-				int32_t ta = player->findAttackSoldiers(wh->base_flag());
-
-				if (ta < 1)
-					continue;
-
-				// extra priority push!
-				int32_t tc = ta * 2;
-
-				if (tc > chance) {
-					target = wh;
-					chance = tc;
-					attackers = ta;
-				}
-			}
-		}
-
-	// Reenque militarysite at the end of list
-	militarysites.push_back(militarysites.front());
-	militarysites.pop_front();
-
-	// Return if chance to win is too low
-	if (chance < 3) {
-		next_attack_consideration_due_ = gametime % 7 * 1000 + gametime;
+
+	// defining treshold ratio of own_strenght/enemy's_strength
+	uint32_t treshold_ratio = 100;
+	if (type == AGGRESSIVE)
+		treshold_ratio = 80;
+	if (type == DEFENSIVE)
+		treshold_ratio = 120;
+
+	iterate_players_existing_novar(p, nr_players, game())++ plr_in_game;
+
+	// receiving games statistics and parsing it (reading latest entry)
+	const Game::General_Stats_vector& genstats = game().get_general_statistics();
+	for (uint8_t j = 1; j <= plr_in_game; ++j) {
+		if (pn == j) {
+			player_attackable[j - 1] = false;
+			continue;
+		}
+
+		if (genstats[j - 1].miltary_strength.back() == 0) {
+			// to avoid improbable zero division
+			player_attackable[j - 1] = true;
+			any_attackable = true;
+		} else if ((genstats[pn - 1].miltary_strength.back() * 100 /
+		            genstats[j - 1].miltary_strength.back()) > treshold_ratio) {
+			player_attackable[j - 1] = true;
+			any_attackable = true;
+		} else {
+			player_attackable[j - 1] = false;
+		}
+		if (kAttackDebug)
+			log(" %2d: %s player %2d (strength: pl: %3d vs en: %3d))\n",
+			    pn,
+			    player_attackable[j - 1] ? "can attack" : "can not attack",
+			    j,
+			    genstats[pn - 1].miltary_strength.back(),
+			    genstats[j - 1].miltary_strength.back());
+	}
+
+	if (not any_attackable) {
+		if (kAttackDebug)
+			log("  %2d: No attackable enemy... returning...\n", pn);
+		next_attack_consideration_due_ = 120 * 1000 + (gametime % 30 + 2) * 1000 + gametime;
 		return false;
 	}
 
-	// Attack the selected target.
-	game().send_player_enemyflagaction(target->base_flag(), pn, attackers);
+	// the logic of attacking is to pick n military buildings - random ones
+	// and test them for possible attack
+	const uint16_t attempts = militarysites.size() / 6 + 1;
+	Map& map = game().map();
+
+	uint16_t position = 0;
+	for (uint32_t i = 0; i < attempts && not any_attacked; ++i) {
+		position = (game().get_gametime() + (3 * i)) % militarysites.size();
+
+		if (kAttackDebug)
+			log("  %2d: Attack consideration #%1d: picking building: %2d/%2d\n",
+			    pn,
+			    i + 1,
+			    position,
+			    militarysites.size());
+
+		// picking random military sites
+		// using gametime as a random value, but it is constant so each next is on position +3
+		// iterating over fields
+		// (std::vector would be much better here)
+
+		std::list<MilitarySiteObserver>::iterator mso = militarysites.begin();
+		std::advance(mso, position);
+
+		MilitarySite* ms = mso->site;
+		Building* target = ms;  // dummy initialisation to silence the compiler
+		uint32_t const vision = ms->vision_range();
+		FCoords f = map.get_fcoords(ms->get_position());
+		int32_t chance = 0;
+		uint32_t attackers = 0;
+		uint32_t defenders = 0;
+		uint32_t defend_ready_enemies = 0;  // enemy soldiers that can come to defend the attacked
+		                                    // building (one soldier has to stay)
+		// uint8_t retreat = ms->owner().get_retreat_percentage();
+
+		// skipping if based on  "enemies nearby" there are probably no enemies nearby
+		if (not mso->enemies_nearby and gametime % 8 > 0) {
+			if (kAttackDebug)
+				log("   %2d: Skipping consideration due to enemies_nearby set to false\n", pn);
+			continue;  // go on with next attempt
+		}
+		if (kAttackDebug)
+			log("   %2d: Scanning nearby buildings\n", pn);
+
+		// setting as default
+		mso->enemies_nearby = false;
+
+		// Search in a radius of the vision of the militarysite and collect
+		// information about immovables in the area
+		std::vector<ImmovableFound> immovables;
+		map.find_immovables(Area<FCoords>(f, vision), &immovables, FindImmovableAttackable());
+
+		for (uint32_t j = 0; j < immovables.size(); ++j) {
+			if (upcast(MilitarySite, bld, immovables.at(j).object)) {
+				if (!player->is_hostile(bld->owner()))
+					continue;
+
+				mso->enemies_nearby = true;
+
+				if (not player_attackable[bld->owner().player_number() - 1]) {
+					if (kAttackDebug)
+						log("     %2d: building of player %2d, not attackable... \n",
+						    pn,
+						    bld->owner().player_number());
+					continue;
+				}
+
+				if (bld->canAttack()) {
+
+					// any_attackable_building=true;
+
+					int32_t ta = player->findAttackSoldiers(bld->base_flag());
+
+					if (type == NORMAL)
+						ta = ta * 2 / 3;
+
+					if (ta < 1)
+						continue;
+
+					int32_t const tc = ta - bld->presentSoldiers().size();
+
+					if (bld->presentSoldiers().size() > 1)
+						defend_ready_enemies += bld->presentSoldiers().size() - 1;
+
+					if (tc > chance) {
+						target = bld;
+						chance = tc;
+						attackers = ta;
+						defenders = bld->presentSoldiers().size();
+					}
+				} else if (kAttackDebug)
+					log("     %2d: building of player %2d, considering for attack \n",
+					    pn,
+					    bld->owner().player_number());
+			} else if (upcast(Warehouse, wh, immovables.at(j).object)) {
+				if (!player->is_hostile(wh->owner()))
+					continue;
+
+				if (wh->canAttack()) {
+					int32_t ta = player->findAttackSoldiers(wh->base_flag());
+
+					if (ta < 1)
+						continue;
+
+					// extra priority push!
+					int32_t tc = ta * 2;
+
+					// we presume that there are no soldiers in warehouse
+					// after long fights this tend to be true :)
+
+					if (tc > chance) {
+						target = wh;
+						chance = tc;
+						attackers = ta;
+						defenders = 0;
+					}
+				}
+			}
+
+			// here we consider enemy soldiers in near buildings.
+			int32_t penalty;
+			if (defend_ready_enemies > 0)
+				penalty = (defenders * 100) / 5 * (defend_ready_enemies * 100) / 10 * 10 / 100;
+			else
+				penalty = 0;
+
+			// Return if chance to win is too low
+			if ((chance - penalty / 100) < 2) {
+				continue;
+			}
+
+			if (kAttackDebug)
+				log("   Player %1d attacking %3dx%3d, chance: %2d-%2d, attackers: %2d, "
+				    "station.defenders: %2d, "
+				    "nearby defenders: %2d, vision: %d \n",
+				    pn,
+				    target->base_flag().get_position().x,
+				    target->base_flag().get_position().y,
+				    chance,
+				    penalty / 100,
+				    attackers,
+				    defenders,
+				    defend_ready_enemies,
+				    vision);
+
+			game().send_player_enemyflagaction(target->base_flag(), pn, attackers);
+
+			any_attacked = true;
+			break;
+		}
+	}
+
+	if (kAttackDebug)
+		log("  %2d: Attacked any?: %s\n", pn, any_attacked ? "Y" : "N");
+
 	//  Do not attack again too soon - returning soldiers must get healed first.
-	next_attack_consideration_due_ = (gametime % 51 + 10) * 1000 + gametime;
-	return true;
+	if (any_attacked)
+		next_attack_consideration_due_ = (gametime % 40 + 10) * 1000 + gametime;
+	else {
+		next_attack_consideration_due_ = (gametime % 80 + 10) * 1000 + gametime;
+	}
+
+	if (any_attacked)
+		return true;
+	else {
+		return false;
+	}
 }

=== modified file 'src/graphic/animation.cc'
--- src/graphic/animation.cc	2014-07-05 14:22:44 +0000
+++ src/graphic/animation.cc	2014-07-08 19:41:26 +0000
@@ -292,13 +292,21 @@
 		//     opengl texture.
 		const Image* pc_image = g_gr->images().get(filename);
 		if (frames_[0]->width() != pc_image->width() or frames_[0]->height() != pc_image->height()) {
-			throw wexception("playercolor mask has wrong size: (%u, %u), should "
-			                 "be (%u, %u) like the animation frame",
-			                 pc_image->width(),
-			                 pc_image->height(),
-			                 frames_[0]->width(),
-			                 frames_[0]->height());
-		}
+			//there was throw wexeption, it crashes game. Consider it when commiting.
+			log("ANIMATION ERROR: playercolor mask has wrong size: (%s: %u, %u), should "
+				 "be (%u, %u) like the animation frame\n",
+				 filename.c_str(), pc_image->width(), pc_image->height(),
+				 frames_[0]->width(), frames_[0]->height());
+				 hasplrclrs_ = false;
+				 break;
+			}
+			//throw wexception("playercolor mask has wrong size: (%u, %u), should "
+			                 //"be (%u, %u) like the animation frame",
+			                 //pc_image->width(),
+			                 //pc_image->height(),
+			                 //frames_[0]->width(),
+			                 //frames_[0]->height());
+		//}
 		pcmasks_.push_back(pc_image);
 	}
 }

=== modified file 'src/logic/findbob.cc'
--- src/logic/findbob.cc	2014-07-03 19:26:30 +0000
+++ src/logic/findbob.cc	2014-07-08 19:41:26 +0000
@@ -47,4 +47,10 @@
 	return bob->get_bob_type() == Bob::SHIP;
 }
 
+bool FindBobCritter::accept(Bob * bob) const
+{
+	return bob->get_bob_type() == Bob::CRITTER;
+}
+
+
 } // namespace Widelands

=== modified file 'src/logic/findbob.h'
--- src/logic/findbob.h	2014-07-05 16:41:51 +0000
+++ src/logic/findbob.h	2014-07-08 19:41:26 +0000
@@ -51,6 +51,10 @@
 	virtual bool accept(Bob * bob) const override;
 };
 
+struct FindBobCritter : FindBob {
+	virtual bool accept(Bob * bob) const override;
+};
+
 
 } // namespace Widelands
 

=== modified file 'src/logic/player.cc'
--- src/logic/player.cc	2014-07-05 14:22:44 +0000
+++ src/logic/player.cc	2014-07-08 19:41:26 +0000
@@ -447,9 +447,6 @@
 
 				if (BaseImmovable * const imm = fc.field->get_immovable())
 					if (imm->get_size() >= BaseImmovable::SMALL) {
-						log
-							("%i: building road, immovable in the way, type=%d\n",
-							 player_number(), imm->get_type());
 						return nullptr;
 					}
 				if (!(get_buildcaps(fc) & MOVECAPS_WALK)) {

=== modified file 'tribes/atlanteans/bakery/conf'
--- tribes/atlanteans/bakery/conf	2014-07-03 20:06:38 +0000
+++ tribes/atlanteans/bakery/conf	2014-07-08 19:41:26 +0000
@@ -3,6 +3,7 @@
 
 [aihints]
 build_material=false
+is_food_basic=true
 
 [buildcost]
 log=2

=== modified file 'tribes/atlanteans/castle/conf'
--- tribes/atlanteans/castle/conf	2014-03-17 17:23:26 +0000
+++ tribes/atlanteans/castle/conf	2014-07-08 19:41:26 +0000
@@ -25,3 +25,9 @@
 [idle]
 pics=castle_i_??.png
 hotspot=91 91
+
+[aihints]
+expansion=true
+fighting=true
+mountain_conqueror=true
+

=== modified file 'tribes/atlanteans/guardhall/conf'
--- tribes/atlanteans/guardhall/conf	2014-03-17 17:23:26 +0000
+++ tribes/atlanteans/guardhall/conf	2014-07-08 19:41:26 +0000
@@ -23,3 +23,6 @@
 [idle]
 pics=guardhall_i_??.png
 hotspot=58 72
+
+[aihints]
+fighting=true

=== modified file 'tribes/atlanteans/guardhouse/conf'
--- tribes/atlanteans/guardhouse/conf	2014-03-17 17:23:26 +0000
+++ tribes/atlanteans/guardhouse/conf	2014-07-08 19:41:26 +0000
@@ -20,3 +20,7 @@
 [idle]
 pics=guardhouse_i_??.png
 hotspot=33 41
+
+[aihints]
+expansion=true
+mountain_conqueror=true

=== modified file 'tribes/atlanteans/small_tower/conf'
--- tribes/atlanteans/small_tower/conf	2014-03-17 17:23:26 +0000
+++ tribes/atlanteans/small_tower/conf	2014-07-08 19:41:26 +0000
@@ -22,3 +22,6 @@
 [idle]
 pics=small_tower_i_??.png
 hotspot=42 65
+
+[aihints]
+fighting=true

=== modified file 'tribes/atlanteans/smokery/conf'
--- tribes/atlanteans/smokery/conf	2014-07-02 16:36:07 +0000
+++ tribes/atlanteans/smokery/conf	2014-07-08 19:41:26 +0000
@@ -15,7 +15,7 @@
 
 [aihints]
 build_material=false
-is_basic=true
+is_food_basic=true
 
 [working positions]
 smoker=1

=== modified file 'tribes/atlanteans/tower/conf'
--- tribes/atlanteans/tower/conf	2014-03-17 17:23:26 +0000
+++ tribes/atlanteans/tower/conf	2014-07-08 19:41:26 +0000
@@ -25,3 +25,7 @@
 [idle]
 pics=tower_i_??.png
 hotspot=55 60
+
+[aihints]
+expansion=true
+mountain_conqueror=true

=== modified file 'tribes/atlanteans/weaving-mill/conf'
--- tribes/atlanteans/weaving-mill/conf	2014-07-02 16:36:07 +0000
+++ tribes/atlanteans/weaving-mill/conf	2014-07-08 19:41:26 +0000
@@ -57,6 +57,10 @@
 pics=weaving_mill_i_??.png  # ???
 hotspot=65 69
 
+[aihints]
+is_basic=true
+
 [working]
 pics=weaving_mill_i_??.png # ???
 hotspot=65 69
+

=== modified file 'tribes/barbarians/donjon/conf'
--- tribes/barbarians/donjon/conf	2014-03-17 17:23:26 +0000
+++ tribes/barbarians/donjon/conf	2014-07-08 19:41:26 +0000
@@ -32,3 +32,8 @@
 [unoccupied]
 pics=donjon_u_??.png
 hotspot=48 84
+
+[aihints]
+expansion=true
+fighting=true
+mountain_conqueror=true

=== modified file 'tribes/barbarians/fortress/conf'
--- tribes/barbarians/fortress/conf	2014-03-17 17:23:26 +0000
+++ tribes/barbarians/fortress/conf	2014-07-08 19:41:26 +0000
@@ -34,3 +34,8 @@
 pics=fortress_i_??.png
 hotspot=103 80
 fps=10
+
+[aihints]
+expansion=true
+fighting=true
+mountain_conqueror=true

=== modified file 'tribes/barbarians/sentry/conf'
--- tribes/barbarians/sentry/conf	2014-03-17 17:23:26 +0000
+++ tribes/barbarians/sentry/conf	2014-07-08 19:41:26 +0000
@@ -27,3 +27,8 @@
 [unoccupied]
 pics=sentry_u_??.png
 hotspot=39 40
+
+[aihints]
+expansion=true
+fighting=true
+mountain_conqueror=true

=== modified file 'tribes/barbarians/tavern/conf'
--- tribes/barbarians/tavern/conf	2014-07-03 20:06:38 +0000
+++ tribes/barbarians/tavern/conf	2014-07-08 19:41:26 +0000
@@ -15,6 +15,7 @@
 
 [aihints]
 build_material=false
+is_food_basic=true
 
 [working positions]
 innkeeper=1

=== modified file 'tribes/empire/barrier/conf'
--- tribes/empire/barrier/conf	2014-03-17 17:23:26 +0000
+++ tribes/empire/barrier/conf	2014-07-08 19:41:26 +0000
@@ -35,3 +35,6 @@
 [idle]
 pics=barrier_i_??.png
 hotspot=49 77
+
+[aihints]
+fighting=true

=== modified file 'tribes/empire/brewery/conf'
--- tribes/empire/brewery/conf	2014-07-03 20:06:38 +0000
+++ tribes/empire/brewery/conf	2014-07-08 19:41:26 +0000
@@ -3,6 +3,7 @@
 
 [aihints]
 build_material=false
+is_food_basic=true
 
 [buildcost]
 log=1

=== modified file 'tribes/empire/farm/conf'
--- tribes/empire/farm/conf	2014-03-10 10:45:21 +0000
+++ tribes/empire/farm/conf	2014-07-08 19:41:26 +0000
@@ -3,6 +3,7 @@
 
 [aihints]
 space_consumer=true
+is_food_basic=true
 
 [buildcost]
 wood=2

=== modified file 'tribes/empire/fortress/conf'
--- tribes/empire/fortress/conf	2014-03-17 06:13:24 +0000
+++ tribes/empire/fortress/conf	2014-07-08 19:41:26 +0000
@@ -33,3 +33,7 @@
 pics=fortress_b_??.png
 hotspot=90 105
 
+[aihints]
+expansion=true
+fighting=true
+mountain_conqueror=true

=== modified file 'tribes/empire/outpost/conf'
--- tribes/empire/outpost/conf	2014-03-17 06:13:24 +0000
+++ tribes/empire/outpost/conf	2014-07-08 19:41:26 +0000
@@ -24,3 +24,6 @@
 [idle]
 pics=outpost_i_??.png
 hotspot=57 77
+
+[aihints]
+expansion=true

=== modified file 'tribes/empire/sentry/conf'
--- tribes/empire/sentry/conf	2014-03-17 17:23:26 +0000
+++ tribes/empire/sentry/conf	2014-07-08 19:41:26 +0000
@@ -30,3 +30,8 @@
 [idle]
 pics=sentry_i_??.png
 hotspot=37 60
+
+[aihints]
+expansion=true
+fighting=true
+mountain_conqueror=true

=== modified file 'tribes/empire/tavern/conf'
--- tribes/empire/tavern/conf	2014-07-03 20:06:38 +0000
+++ tribes/empire/tavern/conf	2014-07-08 19:41:26 +0000
@@ -14,6 +14,7 @@
 
 [aihints]
 build_material=false
+is_food_basic=true
 
 [working positions]
 innkeeper=1

=== modified file 'tribes/empire/tower/conf'
--- tribes/empire/tower/conf	2014-03-17 06:13:24 +0000
+++ tribes/empire/tower/conf	2014-07-08 19:41:26 +0000
@@ -29,3 +29,6 @@
 [build]
 pics=tower_b_??.png
 hotspot=53 81
+
+[aihints]
+mountain_conqueror=true

=== modified file 'tribes/empire/vineyard/conf'
--- tribes/empire/vineyard/conf	2014-03-16 20:55:15 +0000
+++ tribes/empire/vineyard/conf	2014-07-08 19:41:26 +0000
@@ -5,6 +5,7 @@
 space_consumer=true
 is_basic=true
 build_material=false
+is_food_basic=true
 
 [buildcost]
 wood=2

=== modified file 'tribes/empire/winery/conf'
--- tribes/empire/winery/conf	2013-07-23 19:04:12 +0000
+++ tribes/empire/winery/conf	2014-07-08 19:41:26 +0000
@@ -3,6 +3,7 @@
 
 [aihints]
 build_material=false
+is_food_basic=true
 
 [buildcost]
 wood=1


Follow ups