← Back to team overview

widelands-dev team mailing list archive

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

 

Review: Needs Fixing

> I would like to avoid creating new branch but if it is really needed I will
do it...

please do, otherwise we merge the back and forth changing of the properties which pollutes the history for no reason.

on superficial looking over the diff it seems like you have not addressed my comments from the first round of reviews. Please do so.

Diff comments:

> === 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-06 20:31:48 +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-06 20:31:48 +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,13 @@
>  	const World& world_;
>  };
>  
> +// struct FindNodeResource {

Why is this still here? Should be deleted.

> +// bool accept(const Map&, const FCoords& fc) const {
> +// printf (" Resource: %d\n",fc.field->get_resources());
> +// return false;
> +//}
> +//};
> +
>  struct FindNodeWithFlagOrRoad {
>  	Economy* economy;
>  	bool accept(const Map&, FCoords) const;
> @@ -174,10 +198,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 +233,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 +244,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 +298,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 +345,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 +356,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-06 20:31:48 +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-06 20:31:48 +0000
> @@ -20,11 +20,10 @@
>  #ifndef WL_AI_AI_HINTS_H
>  #define WL_AI_AI_HINTS_H
>  
> -#include <stdint.h>
> -
> +#include <SDL_types.h>

I commented on that before too. This should not be here.

>  #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-06 20:31:48 +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,31 @@
>  		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) {
> +			// FindNodeResource find_fish;
> +			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 +626,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 +691,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 +771,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 +820,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 +841,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 +851,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 +893,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 +919,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 +982,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 +1019,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 +1070,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 +1104,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 +1118,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 +1178,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 +1225,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 +1255,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 +1273,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 +1285,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 +1320,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 +1372,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 +1382,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 +1407,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 +1457,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 +1478,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 +1519,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 +1646,7 @@
>  		if (kWinnerDebug)
>  			log(" TDEBUG:  no building picked up\n");
>  
> +		mine = false;
>  		return false;
>  	}
>  
> @@ -1575,15 +1656,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");
> @@ -1944,24 +2037,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 +2064,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 +2110,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 +2127,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 +2168,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 +2227,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 +2334,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 +2359,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 +2396,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 +2423,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 +2442,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 +2485,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 +2495,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 +2528,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 +2553,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 +2561,6 @@
>  			log(" MINES_UPDATE:    ..enhancing\n");
>  	}
>  
> -	//// Reorder and set new values;
> -	// mines_.push_back(mines_.front());
> -	// mines_.pop_front();
>  	return changed;
>  }
>  
> @@ -2439,7 +2577,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 +2656,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 +2719,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 +2747,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);
> @@ -2764,6 +2905,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 +2917,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,6 +2929,7 @@
>  			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_;
>  	}
> @@ -2796,6 +2940,7 @@
>  	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 +2949,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 +2968,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;
>  				}
> @@ -2881,76 +3029,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-06 20:31:48 +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-06 20:31:48 +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-06 20:31:48 +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-06 20:31:48 +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-03-17 17:23:26 +0000
> +++ tribes/atlanteans/bakery/conf	2014-07-06 20:31:48 +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-06 20:31:48 +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-06 20:31:48 +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-06 20:31:48 +0000
> @@ -20,3 +20,7 @@
>  [idle]
>  pics=guardhouse_i_??.png
>  hotspot=33 41
> +
> +[aihints]
> +expansion=true
> +mountain_conqueror=true
> 
> === modified file 'tribes/atlanteans/pics/frontier_00.png' (properties changed: +x to -x)
> === modified file 'tribes/atlanteans/pics/frontier_00_pc.png' (properties changed: +x to -x)
> === 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-06 20:31:48 +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-06-06 20:27:28 +0000
> +++ tribes/atlanteans/smokery/conf	2014-07-06 20:31:48 +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-06 20:31:48 +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-03-17 17:23:26 +0000
> +++ tribes/atlanteans/weaving-mill/conf	2014-07-06 20:31:48 +0000
> @@ -53,3 +53,6 @@
>  [idle]
>  pics=weaving_mill_i_??.png  # ???
>  hotspot=65 69
> +
> +[aihints]
> +is_basic=true
> 
> === modified file 'tribes/barbarians/donjon/conf'
> --- tribes/barbarians/donjon/conf	2014-03-17 17:23:26 +0000
> +++ tribes/barbarians/donjon/conf	2014-07-06 20:31:48 +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-06 20:31:48 +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/pics/frontier_00.png' (properties changed: +x to -x)
> === modified file 'tribes/barbarians/pics/frontier_00_pc.png' (properties changed: +x to -x)
> === modified file 'tribes/barbarians/sentry/conf'
> --- tribes/barbarians/sentry/conf	2014-03-17 17:23:26 +0000
> +++ tribes/barbarians/sentry/conf	2014-07-06 20:31:48 +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-03-17 17:23:26 +0000
> +++ tribes/barbarians/tavern/conf	2014-07-06 20:31:48 +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-06 20:31:48 +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-03-17 17:23:26 +0000
> +++ tribes/empire/brewery/conf	2014-07-06 20:31:48 +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-06 20:31:48 +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-06 20:31:48 +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-06 20:31:48 +0000
> @@ -24,3 +24,6 @@
>  [idle]
>  pics=outpost_i_??.png
>  hotspot=57 77
> +
> +[aihints]
> +expansion=true
> 
> === modified file 'tribes/empire/pics/frontier_00.png' (properties changed: +x to -x)
> === modified file 'tribes/empire/pics/frontier_00_pc.png' (properties changed: +x to -x)
> === modified file 'tribes/empire/sentry/conf'
> --- tribes/empire/sentry/conf	2014-03-17 17:23:26 +0000
> +++ tribes/empire/sentry/conf	2014-07-06 20:31:48 +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	2013-07-23 19:04:12 +0000
> +++ tribes/empire/tavern/conf	2014-07-06 20:31:48 +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-06 20:31:48 +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-06 20:31:48 +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-06 20:31:48 +0000
> @@ -3,6 +3,7 @@
>  
>  [aihints]
>  build_material=false
> +is_food_basic=true
>  
>  [buildcost]
>  wood=1
> 


-- 
https://code.launchpad.net/~widelands-dev/widelands/tibor-ai3/+merge/225401
Your team Widelands Developers is subscribed to branch lp:~widelands-dev/widelands/tibor-ai3.


References