← Back to team overview

widelands-dev team mailing list archive

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

 

I added a bunch of nitpicky code style comments. Can you please fix these? They will make the code a lot easier to read for others :)

Diff comments:

> === modified file 'src/ai/ai_help_structs.cc'
> --- src/ai/ai_help_structs.cc	2014-09-19 12:54:54 +0000
> +++ src/ai/ai_help_structs.cc	2014-10-03 21:34:06 +0000
> @@ -25,21 +25,24 @@
>  namespace Widelands {
>  
>  // FindNodeWithFlagOrRoad
> -
>  bool FindNodeWithFlagOrRoad::accept(const Map&, FCoords fc) const {
>  	if (upcast(PlayerImmovable const, pimm, fc.field->get_immovable()))
> -		return pimm->get_economy() != economy && (dynamic_cast<Flag const*>(pimm)
> -		                                          || (dynamic_cast<Road const*>(pimm) &&
> -		                                             (fc.field->nodecaps() & BUILDCAPS_FLAG)));
> +		return (dynamic_cast<Flag const*>(pimm) ||
> +		        (dynamic_cast<Road const*>(pimm) && (fc.field->nodecaps() & BUILDCAPS_FLAG)));
>  	return false;
>  }
>  
>  // CheckStepRoadAI
>  
> -bool CheckStepRoadAI::allowed(Map& map, FCoords, FCoords end, int32_t, CheckStep::StepId const id)
> -   const {
> +bool CheckStepRoadAI::allowed(
> +   Map& map, FCoords start, FCoords end, int32_t, CheckStep::StepId const id) const {
>  	uint8_t endcaps = player_->get_buildcaps(end);
>  
> +	// we should not cross fields with road or flags (or any other immovable)
> +	if ((map.get_immovable(start)) && !(id == CheckStep::stepFirst)) {
> +		return false;
> +	}
> +
>  	// Calculate cost and passability
>  	if (!(endcaps & movecaps_))
>  		return false;
> 
> === modified file 'src/ai/ai_help_structs.h'
> --- src/ai/ai_help_structs.h	2014-09-19 12:54:54 +0000
> +++ src/ai/ai_help_structs.h	2014-10-03 21:34:06 +0000
> @@ -137,9 +137,7 @@
>  	const World& world_;
>  };
>  
> -
>  struct FindNodeWithFlagOrRoad {
> -	Economy* economy;
>  	bool accept(const Map&, FCoords) const;
>  };
>  
> @@ -166,6 +164,13 @@
>  	}
>  };
>  
> +// ordering nearflags by biggest reduction
> +struct CompareShortening {
> +	bool operator()(const NearFlag& a, const NearFlag& b) const {
> +		return (a.cost_ - a.distance_) > (b.cost_ - b.distance_);
> +	}
> +};
> +
>  struct WalkableSpot {
>  	Coords coords;
>  	bool has_flag_;
> @@ -191,7 +196,6 @@
>  
>  	int32_t next_update_due_;
>  
> -	bool reachable;
>  	bool preferred_;
>  	bool enemy_nearby_;
>  
> @@ -220,6 +224,10 @@
>  	int16_t military_presence_;
>  	// stationed (manned) military buildings nearby
>  	int16_t military_stationed_;
> +	// some buildings must be postponed bit
> +	int32_t prohibited_till_;
> +	// and then some must be forced
> +	int32_t forced_after_;
>  
>  	std::vector<uint8_t> consumers_nearby_;
>  	std::vector<uint8_t> producers_nearby_;
> @@ -227,7 +235,6 @@
>  	BuildableField(const Widelands::FCoords& fc)
>  	   : coords(fc),
>  	     next_update_due_(0),
> -	     reachable(false),
>  	     preferred_(false),
>  	     enemy_nearby_(0),
>  	     unowned_land_nearby_(0),
> @@ -259,13 +266,12 @@
>  
>  	int32_t next_update_due_;
>  
> -	bool reachable;
>  	bool preferred_;
>  
>  	int32_t mines_nearby_;
>  
>  	MineableField(const Widelands::FCoords& fc)
> -	   : coords(fc), next_update_due_(0), reachable(false), preferred_(false), mines_nearby_(0) {
> +	   : coords(fc), next_update_due_(0), preferred_(false), mines_nearby_(0) {
>  	}
>  };
>  
> @@ -296,22 +302,22 @@
>  		MINE
>  	} type;
>  
> -	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 is_hunter_;           // need to identify hunters
> +	bool is_fisher_;           // 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
> +	int32_t prohibited_till_;  // do not build before (ms)
> +	int32_t forced_after_;     // do not wait until ware is needed
>  
>  	bool unoccupied_;  //
>  
> @@ -347,6 +353,7 @@
>  	int32_t built_time_;
>  	int32_t unoccupied_till_;
>  	uint8_t stats_zero_;
> +	uint8_t no_resources_count;
>  	BuildingObserver* bo;
>  };
>  
> 
> === modified file 'src/ai/ai_hints.cc'
> --- src/ai/ai_hints.cc	2014-07-14 10:45:44 +0000
> +++ src/ai/ai_hints.cc	2014-10-03 21:34:06 +0000
> @@ -32,12 +32,8 @@
>  BuildingHints::BuildingHints(Section* const section)
>     : 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),
> @@ -45,6 +41,8 @@
>       expansion_(section ? section->get_bool("expansion") : false),
>       fighting_(section ? section->get_bool("fighting") : false),
>       mountain_conqueror_(section ? section->get_bool("mountain_conqueror") : false),
> +     prohibited_till_(section ? section->get_int("prohibited_till", 0) : 0),
> +     forced_after_(section ? section->get_int("forced_after", 864000) : 0),  // 10 days default
>       mines_percent_(section ? section->get_int("mines_percent", 100) : 0) {
>  	if (section) {
>  		if (char const* const s = section->get_string("renews_map_resource"))
> 
> === modified file 'src/ai/ai_hints.h'
> --- src/ai/ai_hints.h	2014-07-15 05:12:37 +0000
> +++ src/ai/ai_hints.h	2014-10-03 21:34:06 +0000
> @@ -41,18 +41,6 @@
>  		return mines_;
>  	}
>  
> -	bool is_basic() const {
> -		return basic_;
> -	}
> -
> -	bool is_food_basic() const {
> -		return food_basic_;
> -	}
> -
> -	bool prod_build_material() const {
> -		return build_material_;
> -	}
> -
>  	bool is_logproducer() const {
>  		return log_producer_;
>  	}
> @@ -61,10 +49,6 @@
>  		return stone_producer_;
>  	}
>  
> -	bool is_marbleproducer() const {
> -		return marble_producer_;
> -	}
> -
>  	bool mines_water() const {
>  		return mines_water_;
>  	}
> @@ -90,6 +74,14 @@
>  		return mountain_conqueror_;
>  	}
>  
> +	int32_t get_prohibited_till() const {
> +		return prohibited_till_;
> +	}
> +
> +	int32_t get_forced_after() const {
> +		return forced_after_;
> +	}
> +
>  	uint8_t get_mines_percent() const {
>  		return mines_percent_;
>  	}
> @@ -97,12 +89,8 @@
>  private:
>  	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_;
> -	bool marble_producer_;
>  	bool needs_water_;
>  	bool mines_water_;
>  	bool recruitment_;  // whether building recruits special workers
> @@ -110,6 +98,8 @@
>  	bool expansion_;
>  	bool fighting_;
>  	bool mountain_conqueror_;
> +	int32_t prohibited_till_;
> +	int32_t forced_after_;
>  	uint8_t mines_percent_;
>  
>  	DISALLOW_COPY_AND_ASSIGN(BuildingHints);
> 
> === modified file 'src/ai/defaultai.cc'
> --- src/ai/defaultai.cc	2014-09-19 12:54:54 +0000
> +++ src/ai/defaultai.cc	2014-10-03 21:34:06 +0000
> @@ -23,6 +23,7 @@
>  #include <ctime>
>  #include <queue>
>  #include <typeinfo>
> +#include <unordered_set>
>  
>  #include "ai/ai_hints.h"
>  #include "base/log.h"
> @@ -44,16 +45,19 @@
>  #include "logic/world/world.h"
>  #include "profile/profile.h"
>  
> +// Building of new military buildings can be restricted
> +constexpr int kFreeExpansion = 1;
> +constexpr int kResourcesOrDefense = 2;
> +constexpr int kDefenseOnly = 3;
> +constexpr int kNoNewMilitary = 4;
> +
>  // following is in miliseconds (widelands counts time in ms)
> -constexpr int kFieldUpdateInterval = 1000;
> +constexpr int kFieldUpdateInterval = 2000;
>  constexpr int kIdleMineUpdateInterval = 22000;
>  constexpr int kBusyMineUpdateInterval = 2000;
>  // building of the same building can be started after 25s at earliest
>  constexpr int kBuildingMinInterval = 25 * 1000;
> -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;
> +constexpr int kMinBFCheckInterval = 6 * 1000;

What does the BF in "kMinBFCheckInterval" mean? Unless this makes lines too long, can you rename this variable? Otherwise, add a comment as to what it does?

I have now found this farther down in a comment, maybe "kBuildableFieldsCheckInterval" would be a good name

>  
>  using namespace Widelands;
>  
> @@ -70,6 +74,8 @@
>       player_(nullptr),
>       tribe_(nullptr),
>       num_constructionsites_(0),
> +     num_milit_constructionsites(0),
> +     num_prod_constructionsites(0),
>       next_road_due_(2000),
>       next_stats_update_due_(30000),
>       next_construction_due_(1000),
> @@ -79,37 +85,53 @@
>       next_militarysite_check_due_(0),
>       next_attack_consideration_due_(300000),
>       next_helpersites_check_due_(180000),
> +     next_bf_check_due_(1000),

As above - what does "bf" mean?

>       inhibit_road_building_(0),
>       time_of_last_construction_(0),
> +     enemy_last_seen_(-2 * 60 * 1000),
>       numof_warehouses_(0),
>       new_buildings_stop_(false),
> +     water_is_important_(false),
> +     mines_need_intensity_ (10),
> +     water_need_intensity_ (4),
>       unstationed_milit_buildings_(0),
> -     military_under_constr_(0),
>       military_last_dismantle_(0),
> -     military_last_build_(0) {
> +     military_last_build_(-60 * 1000),
> +     spots_(0) {
>  
>  	// Subscribe to NoteFieldPossession.
>  	field_possession_subscriber_ =
> -		Notifications::subscribe<NoteFieldPossession>([this](const NoteFieldPossession& note) {
> -			if (note.player != player_) {
> -				return;
> -			}
> -			if (note.ownership == NoteFieldPossession::Ownership::GAINED) {
> -				unusable_fields.push_back(note.fc);
> -			}
> +	   Notifications::subscribe<NoteFieldPossession>([this](const NoteFieldPossession& note) {
> +		   	if (note.player != player_) {
> +			   return;
> +		   }
> +		   	if (note.ownership == NoteFieldPossession::Ownership::GAINED) {
> +			   unusable_fields.push_back(note.fc);
> +		   }
>  		});
>  
>  	// Subscribe to NoteImmovables.
>  	immovable_subscriber_ =
> -		Notifications::subscribe<NoteImmovable>([this](const NoteImmovable& note) {
> -			if (note.pi->owner().player_number() != player_->player_number()) {
> -				return;
> -			}
> -			if (note.ownership == NoteImmovable::Ownership::GAINED) {
> -				gain_immovable(*note.pi);
> -			} else {
> -				lose_immovable(*note.pi);
> -			}
> +	   Notifications::subscribe<NoteImmovable>([this](const NoteImmovable& note) {
> +		   	if (note.pi->owner().player_number() != player_->player_number()) {
> +			   return;
> +		   }
> +		   	if (note.ownership == NoteImmovable::Ownership::GAINED) {
> +			   gain_immovable(*note.pi);
> +		   } else {
> +			   lose_immovable(*note.pi);
> +		   }
> +		});
> +
> +	// Subscribe to ProductionSiteOutOfResources.
> +	outofresource_subscriber_ = Notifications::subscribe<NoteProductionSiteOutOfResources>(
> +	   [this](const NoteProductionSiteOutOfResources& note) {
> +		   	if (note.ps->owner().player_number() != player_->player_number()) {
> +			   return;
> +		   }
> +
> +		   out_of_resources_site(*note.ps);
> +
>  		});
>  }
>  
> @@ -142,23 +164,24 @@
>  
>  	const int32_t gametime = game().get_gametime();
>  
> -	if (m_buildable_changed) {
> +	if (m_buildable_changed || next_bf_check_due_ < gametime) {
>  		// update statistics about buildable fields
>  		update_all_buildable_fields(gametime);
> +		next_bf_check_due_ = gametime + kMinBFCheckInterval;
>  	}
>  
>  	m_buildable_changed = false;
>  
> -	// if there are more than one economy try to connect them with a road.
> +	// perpetually tries to improve roads
>  	if (next_road_due_ <= gametime) {
>  		next_road_due_ = gametime + 1000;
>  
> -		if (construct_roads(gametime)) {
> +		if (improve_roads(gametime)) {
>  			m_buildable_changed = true;
>  			return;
>  		}
>  	} else
> -		// only go on, after defaultAI tried to connect all economies.
> +		// only go on, after defaultAI tried to improve roads.
>  		return;
>  
>  	// NOTE Because of the check above, the following parts of think() are used
> @@ -190,6 +213,7 @@
>  
>  		if (construct_building(gametime)) {
>  			time_of_last_construction_ = gametime;
> +			m_buildable_changed = true;
>  			return;
>  		}
>  	}
> @@ -208,16 +232,12 @@
>  		return;
>  
>  	// improve existing roads!
> -	// This sounds important, but actually is not as important as the other
> -	// actions are. Reasons are the following:
> -	//    * The "donkey feature" made economies more stable, even with stupid
> -	//      roads.
> -	//    * If defaultAI builds too much roads, it will waste good building
> -	//      space.
> +	// main part of this improvment is creation 'shortcut roads'
> +	// this includes also connection of new buildings
>  	if (improve_roads(gametime)) {
>  		m_buildable_changed = true;
>  		m_mineable_changed = true;
> -		inhibit_road_building_ = gametime + 2500;
> +		// inhibit_road_building_ = gametime + 1000;

Do you still need this line? If so, please add a TODO comment. Otherwise, remove.

>  		return;
>  	}
>  }
> @@ -257,7 +277,7 @@
>  		bo.type = BuildingObserver::BORING;
>  		bo.cnt_built_ = 0;
>  		bo.cnt_under_construction_ = 0;
> -		bo.cnt_target_ = 0;
> +		bo.cnt_target_ = 1;  // default for everything
>  		bo.stocklevel_ = 0;
>  		bo.stocklevel_time = 0;
>  		bo.last_dismantle_time_ = 0;
> @@ -267,12 +287,9 @@
>  		bo.production_hint_ = -1;
>  		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();
> -		bo.mines_marble_ = bh.is_marbleproducer();
>  		bo.need_water_ = bh.get_needs_water();
>  		bo.mines_water_ = bh.mines_water();
>  		bo.recruitment_ = bh.for_recruitment();
> @@ -280,9 +297,10 @@
>  		bo.expansion_type_ = bh.is_expansion_type();
>  		bo.fighting_type_ = bh.is_fighting_type();
>  		bo.mountain_conqueror_ = bh.is_mountain_conqueror();
> +		bo.prohibited_till_ = bh.get_prohibited_till() * 1000;  // value in conf is in seconds
> +		bo.forced_after_ = bh.get_forced_after() * 1000;        // value in conf is in seconds
>  		if (char const* const s = bh.get_renews_map_resource()) {
>  			bo.production_hint_ = tribe_->safe_ware_index(s);
> -
>  		}
>  
>  		// I just presume cut wood is named "log" in the game
> @@ -294,7 +312,7 @@
>  		// Read all interesting data from ware producing buildings
>  		if (typeid(bld) == typeid(ProductionSiteDescr)) {
>  			const ProductionSiteDescr& prod =
> -				ref_cast<ProductionSiteDescr const, BuildingDescr const>(bld);
> +			   ref_cast<ProductionSiteDescr const, BuildingDescr const>(bld);
>  			bo.type = bld.get_ismine() ? BuildingObserver::MINE : BuildingObserver::PRODUCTIONSITE;
>  			for (const WareAmount& temp_input : prod.inputs()) {
>  				bo.inputs_.push_back(temp_input.first);
> @@ -311,16 +329,17 @@
>  				bo.mines_percent_ = bh.get_mines_percent();
>  			}
>  
> -			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 && tribe_->safe_ware_index("meat") == bo.outputs_.at(0)) {
>  				bo.is_hunter_ = true;
>  			} else
>  				bo.is_hunter_ = false;
>  
> +			// and fishers
> +			if (bo.outputs_.size() == 1 && tribe_->safe_ware_index("fish") == bo.outputs_.at(0)) {
> +				bo.is_fisher_ = true;
> +			} else
> +				bo.is_fisher_ = false;
>  			continue;
>  		}
>  
> @@ -346,10 +365,16 @@
>  	}
>  
>  	num_constructionsites_ = 0;
> +	num_milit_constructionsites = 0;
> +	num_prod_constructionsites = 0;
>  	next_construction_due_ = 0;
>  	next_road_due_ = 1000;
>  	next_productionsite_check_due_ = 0;
>  	inhibit_road_building_ = 0;
> +	// if atlanteans they consider water as a resource
> +	//(together with mines, stones and wood)
> +	if (tribe_->name() == "atlanteans")
> +		water_is_important_ = true;
>  	// Add all fields that we own
>  	Map& map = game().map();
>  	std::set<OPtr<PlayerImmovable>> found_immovables;
> @@ -381,7 +406,11 @@
>   * milliseconds if the area the computer owns is big.
>   */
>  void DefaultAI::update_all_buildable_fields(const int32_t gametime) {
> -	while (!buildable_fields.empty() && buildable_fields.front()->next_update_due_ <= gametime) {
> +
> +	uint16_t i = 0;
> +
> +	while (!buildable_fields.empty() && buildable_fields.front()->next_update_due_ <= gametime &&
> +	       i < 25) {

How about a "for" loop? This will make the code easier to read, and we save 2 lines.

for (uint16_t i = 0; !buildable_fields.empty() && buildable_fields.front()->next_update_due_ <= gametime &&
502	+ i < 25; i++) {

>  		BuildableField& bf = *buildable_fields.front();
>  
>  		//  check whether we lost ownership of the node
> @@ -403,6 +432,8 @@
>  		bf.next_update_due_ = gametime + kFieldUpdateInterval;
>  		buildable_fields.push_back(&bf);
>  		buildable_fields.pop_front();
> +
> +		i += 1;
>  	}
>  }
>  
> @@ -413,7 +444,11 @@
>   * milliseconds if the area the computer owns is big.
>   */
>  void DefaultAI::update_all_mineable_fields(const int32_t gametime) {
> -	while (!mineable_fields.empty() && mineable_fields.front()->next_update_due_ <= gametime) {
> +
> +	uint16_t i = 0;  // counter, used to track # of checked fields
> +
> +	while (!mineable_fields.empty() && mineable_fields.front()->next_update_due_ <= gametime &&
> +	       i < 40) {

"for" loop?

>  		MineableField* mf = mineable_fields.front();
>  
>  		//  check whether we lost ownership of the node
> @@ -435,6 +470,8 @@
>  		mf->next_update_due_ = gametime + kFieldUpdateInterval;  // in fact this has very small effect
>  		mineable_fields.push_back(mf);
>  		mineable_fields.pop_front();
> +
> +		i += 1;
>  	}
>  }
>  
> @@ -495,13 +532,16 @@
>  	}
>  
>  	// to save some CPU
> -	if (mines_.size() > 8 && game().get_gametime() % 3 > 0)
> +	if ((mines_.size() > 8 && game().get_gametime() % 3 > 0) || field.unowned_land_nearby_ == 0)

Since "else" now has {}, give "if" {} as well

>From http://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Conditionals

"if one part of an if-else statement uses curly braces, the other part must too"

>  		field.unowned_mines_pots_nearby_ = 0;
> -	else
> -		field.unowned_mines_pots_nearby_ = map.find_fields(
> -		   Area<FCoords>(field.coords, range + 4),
> -		   nullptr,
> -		   find_unowned_mines_pots);  //+2: a mine can mine raw materials from some range
> +	else {
> +		uint32_t close_mines =
> +		   map.find_fields(Area<FCoords>(field.coords, 4), nullptr, find_unowned_mines_pots);
> +		uint32_t distant_mines =
> +		   map.find_fields(Area<FCoords>(field.coords, range + 6), nullptr, find_unowned_mines_pots);
> +		distant_mines = distant_mines - close_mines;
> +		field.unowned_mines_pots_nearby_ = 6 * close_mines + distant_mines;
> +	}
>  
>  	// collect information about resources in the area
>  	std::vector<ImmovableFound> immovables;
> @@ -512,7 +552,6 @@
>  	// (second is used in check_militarysites)
>  	if (!military) {
>  		int32_t const tree_attr = MapObjectDescr::get_attribute_id("tree");
> -		field.reachable = false;
>  		field.preferred_ = false;
>  		field.enemy_nearby_ = false;
>  		field.military_capacity_ = 0;
> @@ -536,7 +575,7 @@
>  		}
>  
>  		// counting fields with fish
> -		if (field.water_nearby_ > 0 && game().get_gametime() % 10 == 0) {
> +		if (field.water_nearby_ > 0 && (field.fish_nearby_ = -1 || game().get_gametime() % 10 == 0)) {
>  			map.find_fields(Area<FCoords>(field.coords, 6),
>  			                &resource_list,
>  			                FindNodeResource(world.get_resource("fish")));
> @@ -554,16 +593,13 @@
>  		map.get_neighbour(field.coords, WALK_SE, &fse);
>  
>  		if (BaseImmovable const* const imm = fse.field->get_immovable())
> -			if (dynamic_cast<Flag const*>(imm)
> -			    || (dynamic_cast<Road const*>(imm) && (fse.field->nodecaps() & BUILDCAPS_FLAG)))
> +			if (dynamic_cast<Flag const*>(imm) ||
> +			    (dynamic_cast<Road const*>(imm) && (fse.field->nodecaps() & BUILDCAPS_FLAG)))
>  				field.preferred_ = true;
>  
>  		for (uint32_t i = 0; i < immovables.size(); ++i) {
>  			const BaseImmovable& base_immovable = *immovables.at(i).object;
>  
> -			if (dynamic_cast<const Flag*>(&base_immovable))
> -				field.reachable = true;
> -
>  			if (upcast(PlayerImmovable const, player_immovable, &base_immovable))
>  
>  				// TODO(unknown): Only continue; if this is an opposing site
> @@ -571,6 +607,7 @@
>  				if (player_immovable->owner().player_number() != pn) {
>  					if (player_->is_hostile(player_immovable->owner()))
>  						field.enemy_nearby_ = true;
> +					enemy_last_seen_ = game().get_gametime();
>  
>  					continue;
>  				}
> @@ -588,7 +625,9 @@
>  
>  				if (dynamic_cast<const ProductionSite*>(building))
>  					consider_productionsite_influence(
> -					   field, immovables.at(i).coords, get_building_observer(building->descr().name().c_str()));
> +					   field,
> +					   immovables.at(i).coords,
> +					   get_building_observer(building->descr().name().c_str()));
>  			}
>  
>  			if (immovables.at(i).object->has_attribute(tree_attr))
> @@ -616,7 +655,15 @@
>  	}
>  
>  	// folowing is done allways (regardless of military or not)
> +
> +	// we get immovables with higher radius
> +	immovables.clear();
> +	map.find_immovables(Area<FCoords>(field.coords, (range < 10) ? 10 : range), &immovables);
>  	field.military_stationed_ = 0;
> +	field.military_in_constr_nearby_ = 0;
> +	field.military_capacity_ = 0;
> +	field.military_loneliness_ = 1000;
> +	field.military_presence_ = 0;
>  
>  	for (uint32_t i = 0; i < immovables.size(); ++i) {
>  		const BaseImmovable& base_immovable = *immovables.at(i).object;
> @@ -644,7 +691,8 @@
>  					const int32_t v = radius - dist;
>  
>  					if (v > 0) {
> -						field.military_capacity_ += 2;
> +						field.military_capacity_ += target_ms_d->get_max_number_of_soldiers() / 2 + 1;
> +						// field.military_capacity_ += 2;

Can this line go? If not, please add a "TODO" comment.

When I comment something out to test if the code works/compiles first, I often add a quick "NOCOM", so I can grep for it and remove before a merge request.

>  						field.military_loneliness_ *= static_cast<double_t>(dist) / radius;
>  						field.military_in_constr_nearby_ += 1;
>  					}
> @@ -663,14 +711,15 @@
>  
>  					if (!militarysite->stationed_soldiers().empty()) {
>  						field.military_stationed_ += 1;
> -					}
> +					} else

curly braces?

> +						// the name does not match much
> +						field.military_in_constr_nearby_ += 1;
>  
>  					field.military_loneliness_ *= static_cast<double_t>(dist) / radius;
>  				}
>  			}
>  		}
>  	}
> -
>  }
>  
>  /// Updates one mineable field
> @@ -679,21 +728,18 @@
>  	std::vector<ImmovableFound> immovables;
>  	Map& map = game().map();
>  	map.find_immovables(Area<FCoords>(field.coords, 5), &immovables);
> -	field.reachable = false;
>  	field.preferred_ = false;
>  	field.mines_nearby_ = 1;
>  	FCoords fse;
>  	map.get_brn(field.coords, &fse);
>  
>  	if (BaseImmovable const* const imm = fse.field->get_immovable())
> -		if (dynamic_cast<Flag const*>(imm)
> -		    || (dynamic_cast<Road const*>(imm) && (fse.field->nodecaps() & BUILDCAPS_FLAG)))
> +		if (dynamic_cast<Flag const*>(imm) ||
> +		    (dynamic_cast<Road const*>(imm) && (fse.field->nodecaps() & BUILDCAPS_FLAG)))
>  			field.preferred_ = true;
>  
>  	for (const ImmovableFound& temp_immovable : immovables) {
> -		if (dynamic_cast<Flag const*>(temp_immovable.object))
> -			field.reachable = true;
> -		else if (upcast(Building const, bld, temp_immovable.object)) {
> +		if (upcast(Building const, bld, temp_immovable.object)) {
>  			if (bld->descr().get_ismine()) {
>  				++field.mines_nearby_;
>  			} else if (upcast(ConstructionSite const, cs, bld)) {
> @@ -708,6 +754,7 @@
>  void DefaultAI::update_productionsite_stats(int32_t const gametime) {
>  	// Updating the stats every 10 seconds should be enough
>  	next_stats_update_due_ = gametime + 10000;
> +	uint16_t fishers_count=0; //used for atlanteans only
>  
>  	// Reset statistics for all buildings
>  	for (uint32_t i = 0; i < buildings_.size(); ++i) {
> @@ -726,6 +773,10 @@
>  		// Add statistics value
>  		productionsites.front().bo->current_stats_ +=
>  		   productionsites.front().site->get_crude_statistics();
> +		   
> +		//counting fishers
> +		if (productionsites.front().bo->is_fisher_)
> +			 fishers_count+=1;
>  
>  		// Check whether this building is completely occupied
>  		productionsites.front().bo->unoccupied_ |= !productionsites.front().site->can_start_working();
> @@ -735,8 +786,14 @@
>  		productionsites.pop_front();
>  	}
>  
> +	if (fishers_count >4)

Space between > and 4. We have more of these, can you please run codecheck and fix?

cmake/codecheck/CodeCheck.py src/* | grep -v "src/third_party"

> +		water_need_intensity_ = 0;
> +	else 
> +		water_need_intensity_ = 4-fishers_count;
> +	//printf (" %2d: water need intensity: %3d%%/ %2d fishers\n",player_number(),100*water_need_intensity_/4,fishers_count);

Can this go? Otherwise, TODO

> +
>  	// for mines_ also
> -	// Check all available productionsites
> +	// Check all available mines
>  	for (uint32_t i = 0; i < mines_.size(); ++i) {
>  		assert(mines_.front().bo->cnt_built_ > 0);
>  		// Add statistics value
> @@ -779,7 +836,6 @@
>  	//  Just used for easy checking whether a mine or something else was built.
>  	bool mine = false;
>  	bool field_blocked = false;
> -	int32_t spots = 0;
>  	uint32_t consumers_nearby_count = 0;
>  	// this is to increase score so also building near borders can be built
>  	int32_t bulgarian_constant = 12;
> @@ -795,53 +851,67 @@
>  	     ++i)
>  		++spots_avail.at((*i)->coords.field->nodecaps() & BUILDCAPS_SIZEMASK);
>  
> -	spots = spots_avail.at(BUILDCAPS_SMALL);
> -	spots += spots_avail.at(BUILDCAPS_MEDIUM);
> -	spots += spots_avail.at(BUILDCAPS_BIG);
> +	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
> +	// here we possible stop building of new buildings
>  	new_buildings_stop_ = false;
> -
> -	if ((militarysites.size() * 2 + 20) <
> -	    productionsites.size()
> -	    || spots<(3 + (static_cast<int32_t>(productionsites.size()) / 5)) || num_constructionsites_>(
> -	       (militarysites.size() + productionsites.size()) / 2)) {
> -		new_buildings_stop_ = true;
> -	}
> -
> -	// sometimes there is to many military buildings in construction, so we must
> +	uint8_t expansion_mode = kFreeExpansion;
> +
> +	// there are couple of reasons why to stop building production buildings
> +	//(note there are numberous exemptions to this stop)
> +	// 1. to not have too many constructionsites
> +	if (num_prod_constructionsites > productionsites.size() / 7 + 2) {
> +		new_buildings_stop_ = true;
> +	}
> +	// 2. to not exhaust all free spots
> +	if (spots_ * 3 / 2 + 5 < static_cast<int32_t>(productionsites.size())) {
> +		new_buildings_stop_ = true;
> +	}
> +	// 3. too keep some proportions production sites vs military sites
> +	if ((num_prod_constructionsites + productionsites.size()) >
> +	    (num_milit_constructionsites + militarysites.size()) * 3) {
> +		new_buildings_stop_ = true;
> +	}
> +	// 4. if we do not have 3 mines at least
> +	if (mines_.size() < 3)
> +		new_buildings_stop_ = true;
> +	// BUT if enemy is nearby, we cancel above stop
> +	if (new_buildings_stop_ && enemy_last_seen_ + 2 * 60 * 1000 > gametime) {
> +		new_buildings_stop_ = false;
> +	}
> +
> +	// sometimes there is too many military buildings in construction, so we must
>  	// prevent initialization of further buildings start
> -	bool new_military_buildings_stop = false;
> -	// in areas close to enemies, above limit is not effective, so we have second one
> -	// more benevolent limit
> -	bool near_enemy_b_buildings_stop = false;
> -	// in some situation expansion just halts because there are not good spots to expand
> -	// so this is a boost to increase a score and allow building a military building on a spot
> -	// that is normally not suitable for building
> -	int32_t military_boost = 1;
> -
> -	int32_t treshold = (militarysites.size() + productionsites.size()) / 100 + 1;
> -
> -	if (unstationed_milit_buildings_ + military_under_constr_ / 3 > treshold) {
> -		new_military_buildings_stop = true;
> -
> -	}
> -
> -	if (unstationed_milit_buildings_ + military_under_constr_ / 3 > 2 * treshold) {
> -		near_enemy_b_buildings_stop = true;
> -
> -	}
> -
> -	// here we deal with situation when for some time no new military building was built
> -	// in fact this is a last time when there were any military buildings in construction
> -	if ((unstationed_milit_buildings_ + military_under_constr_) > 0)
> -		military_last_build_ = game().get_gametime();
> -
> -	if (military_last_build_ + 1 * 60 * 1000 < game().get_gametime()) {
> -		military_boost = 200;
> -	}
> -
> -	// BuildingIndex proposed_building = INVALID_INDEX; // I need BuildingObserver not index
> +	const uint32_t treshold = militarysites.size() / 40 + 2;
> +
> +	if (unstationed_milit_buildings_ + num_milit_constructionsites > 3 * treshold)
> +		expansion_mode = kNoNewMilitary;
> +	else if (unstationed_milit_buildings_ + num_milit_constructionsites > 2 * treshold)
> +		expansion_mode = kDefenseOnly;
> +	else if (unstationed_milit_buildings_ + num_milit_constructionsites > 1 * treshold)
> +		expansion_mode = kResourcesOrDefense;
> +	else
> +		expansion_mode = kFreeExpansion;
> +
> +	// slowing down the expansion also because of new_buildings_stop_
> +	if (new_buildings_stop_ && unstationed_milit_buildings_ + num_milit_constructionsites > 0 &&
> +	    spots_avail.at(BUILDCAPS_BIG) > 3)
> +		expansion_mode += 1;
> +	if (expansion_mode > kNoNewMilitary)
> +		expansion_mode = kNoNewMilitary;
> +
> +	//we must consider need for mines
> +	const int32_t virtual_mines = mines_.size()+ mineable_fields.size()/10;
> +	if (virtual_mines<4)
> +		mines_need_intensity_ = 10;
> +	else if (virtual_mines>14) 
> +			mines_need_intensity_ = 0;
> +	else
> +		mines_need_intensity_ = 14-virtual_mines;
> +	//printf (" %1d: mines need intensity: %3d%% / %2d mines\n",player_number(),100*mines_need_intensity_/10,mines_.size());

Delete? or TODO

> +	
>  	BuildingObserver* best_building = nullptr;
>  	int32_t proposed_priority = 0;
>  	Coords proposed_coords;
> @@ -864,11 +934,10 @@
>  	     ++i) {
>  		BuildableField* const bf = *i;
>  
> -		if (!bf->reachable)
> -			continue;
> -
> -		// add randomnes and ease AI
> -		if (time(nullptr) % 5 == 0)
> +		// if bf update is overdue for more then 8 seconds
> +		// this will also speed up the game
> +		// this way there should be allways more then 100 bf evaluated
> +		if (bf->next_update_due_ < gametime - 8000)
>  			continue;
>  
>  		// Continue if field is blocked at the moment
> @@ -893,13 +962,23 @@
>  			if (!bo.buildable(*player_))
>  				continue;
>  
> -			if (time(nullptr) % 3 == 0)
> +			if (bo.prohibited_till_ > gametime) {
> +				continue;
> +			}
> +
> +			// if current field is not big enough
> +			if (bo.desc->get_size() > maxsize)
> +				continue;
> +
> +			if (time(nullptr) % 3 == 0 && bo.total_count() > 0)
>  				continue;  // add randomnes and ease AI
>  
>  			if (bo.type == BuildingObserver::MINE)
>  				continue;
>  
> -			if (gametime - bo.construction_decision_time_ < kBuildingMinInterval)
> +			// here we do an exemption for lumberjacs, mainly in early stages of game
> +			// sometimes the first one is not built and AI waits too long for second attempt
> +			if (gametime - bo.construction_decision_time_ < kBuildingMinInterval && !bo.need_trees_)
>  				continue;
>  
>  			if (bo.unoccupied_)
> @@ -909,49 +988,15 @@
>  				continue;
>  
>  			// so we are going to seriously evaluate this building on this field,
> -			// first some base info
> -			// if at least on of outputs is needed
> -			output_is_needed = false;
> -			// max presiousness of outputs
> -			max_preciousness = 0;
> -			// max preciousness of most needed output
> -			max_needed_preciousness = 0;
> -
> -			// Check if the produced wares are needed (if it is producing anything)
> -			if (!bo.outputs_.empty()) {
> -				for (EconomyObserver* observer : economies) {
> -					// Don't check if the economy has no warehouse.
> -					if (observer->economy.warehouses().empty())
> -						continue;
> -
> -					for (uint32_t m = 0; m < bo.outputs_.size(); ++m) {
> -						WareIndex wt(static_cast<size_t>(bo.outputs_.at(m)));
> -
> -						if (observer->economy.needs_ware(wt)) {
> -							output_is_needed = true;
> -
> -							if (wares.at(bo.outputs_.at(m)).preciousness_ > max_needed_preciousness)
> -								max_needed_preciousness = wares.at(bo.outputs_.at(m)).preciousness_;
> -
> -							max_preciousness = wares.at(bo.outputs_.at(m)).preciousness_;
> -						} else {
> -							if (wares.at(bo.outputs_.at(m)).preciousness_ > max_preciousness)
> -								max_preciousness = wares.at(bo.outputs_.at(m)).preciousness_;
> -						}
> -					}
> -				}
> -			}
> +			// first some base info - is its output needed at all?
> +			check_ware_needeness(bo, &output_is_needed, &max_preciousness, &max_needed_preciousness);

Rename to check_ware_necessity? Function name has a typo in any case.

>  
>  			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;
> -
>  			if (bo.type == BuildingObserver::PRODUCTIONSITE) {
>  
>  				// exclude spots on border
> -				if (bf->near_border_ && !bo.need_trees_ && !bo.need_stones_)
> +				if (bf->near_border_ && !bo.need_trees_ && !bo.need_stones_ && !bo.is_fisher_)
>  					continue;
>  
>  				// this can be only a well (as by now)
> @@ -961,32 +1006,52 @@
>  
>  					if (bo.cnt_under_construction_ + bo.unoccupied_ > 0)
>  						continue;
> -					if ((bo.cnt_built_ + bo.unoccupied_) > 0 && gametime < kBaseInfrastructureTime)
> -						continue;
> -					if (new_buildings_stop_)
> -						continue;
> -					bo.cnt_target_ =
> -					   2 + static_cast<int32_t>(mines_.size() + productionsites.size()) / 20;
> -					if ((bo.cnt_built_ + bo.cnt_under_construction_ + bo.unoccupied_) > bo.cnt_target_)
> -						continue;
> +
> +					prio = 0;
> +					// one well is forced
> +					if (bo.total_count() == 0)
> +						prio = 200;  // boost for first/only well
> +					else if (new_buildings_stop_)
> +						continue;
> +
> +					bo.cnt_target_ = 1 + productionsites.size() / 50;
>  
>  					if (bo.stocklevel_time < game().get_gametime() - 30 * 1000) {
>  						bo.stocklevel_ = get_stocklevel(bo);
>  						bo.stocklevel_time = game().get_gametime();
>  					}
> -					if (bo.stocklevel_ > 50)
> +					if (bo.stocklevel_ > 40)
>  						continue;
> -					prio = bf->ground_water_ - 2;
> +					prio += bf->ground_water_ - 2;
>  					prio = recalc_with_border_range(*bf, prio);
>  
>  				} else if (bo.need_trees_) {  // LUMBERJACS
>  
> -					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 - bf->producers_nearby_.at(bo.outputs_.at(0)) * 5 -
> -						   new_buildings_stop_ * 15;  //+ bf->producers_nearby_.at(bo.outputs_.at(0))*5;
> +					bo.cnt_target_ =
> +					   3 + static_cast<int32_t>(mines_.size() + productionsites.size()) / 15;
> +
> +					if (bo.total_count() == 0)
> +						prio = 500 + bf->trees_nearby_;
> +
> +					else if (bo.total_count() == 1)
> +						prio = 400 + bf->trees_nearby_;
> +
> +					else if (bf->trees_nearby_ < 2)
> +						continue;
> +
> +					else {
> +
> +						if (bo.total_count() < bo.cnt_target_)
> +							prio = 75;
> +						else
> +							prio = 0;
> +
> +						prio += 2 * bf->trees_nearby_ - 10 -
> +						        bf->producers_nearby_.at(bo.outputs_.at(0)) * 5 -
> +						        new_buildings_stop_ * 15;
> +
> +						if (bf->near_border_)
> +							prio = prio / 2;
>  					}
>  
>  				} else if (bo.need_stones_) {
> @@ -998,20 +1063,66 @@
>  						continue;
>  					prio = bf->stones_nearby_;
>  
> +					if (prio <= 0)
> +						continue;
> +
> +					if (bo.total_count() == 0)
> +						prio += 150;
> +
>  					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_ < 20)
> -						prio = prio * 2;
> -
> -					if (bo.total_count() == 0)
> -						prio = prio * 5;
> +					if (bo.stocklevel_ == 0)
> +						prio *= 2;
>  
>  					// to prevent to many quaries on one spot
>  					prio = prio - 50 * bf->producers_nearby_.at(bo.outputs_.at(0));
>  
> +					if (bf->near_border_)
> +						prio = prio / 2;
> +
> +				} else if (bo.is_hunter_) {
> +					if (bf->critters_nearby_ < 5)
> +						continue;
> +
> +					if (new_buildings_stop_)
> +						continue;
> +
> +					prio +=
> +					   (bf->critters_nearby_ * 2) - 8 - 5 * bf->producers_nearby_.at(bo.outputs_.at(0));
> +
> +				} else if (bo.is_fisher_) {  // fisher
> +
> +					// ~are fishes needed?
> +					if (max_needed_preciousness == 0)
> +						continue;
> +
> +					if (bo.cnt_under_construction_ + bo.unoccupied_ > 0)
> +						continue;
> +
> +					if (bf->water_nearby_ < 5)
> +						continue;
> +
> +					// we use preciousness to allow atlanteans to build the fishers huts
> +					// atlanteans have preciousness 4, other tribes 3
> +					if (max_needed_preciousness < 4 && new_buildings_stop_)
> +						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();
> +					}
> +
> +					if (bo.stocklevel_ > 50)
> +						continue;
> +
> +					if (bf->producers_nearby_.at(bo.outputs_.at(0)) >= 1)
> +						continue;
> +
> +					prio = bf->fish_nearby_ - new_buildings_stop_ * 15 * bo.total_count();
> +
>  				} else if (bo.production_hint_ >= 0) {
>  					// first setting targets (needed also for dismantling)
>  					if (bo.plants_trees_)
> @@ -1024,77 +1135,75 @@
>  					if ((bo.cnt_under_construction_ + bo.unoccupied_) > 1)
>  						continue;
>  
> -					// production hint (f.e. associate forester with logs)
> -
> -					if (bo.need_water_ && bf->water_nearby_ < 5)  // probably some of them needs water
> -						continue;
> -
>  					if (bo.plants_trees_) {  // RANGERS
>  
>  						// if there are too many trees nearby
> -						if (bf->trees_nearby_ > 25 && bo.total_count() >= 2)
> +						if (bf->trees_nearby_ > 25 && bo.total_count() >= 1)
>  							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;
> -
> -					} else if (gametime > kBaseInfrastructureTime &&
> -					                         !new_buildings_stop_) {  // gamekeepers or so
> -						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_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.total_count() == 0)
> +							prio = 200;
> +						if (bo.total_count() > 2 * bo.cnt_target_)
> +							continue;
> +						// we can go above target if there is shortage of logs on stock
> +						else if (bo.total_count() >= bo.cnt_target_ && bo.stocklevel_ > 40)
> +							continue;
> +
> +						// considering near trees and producers
> +						prio += (30 - bf->trees_nearby_) * 2 +
> +						        bf->producers_nearby_.at(bo.production_hint_) * 5 -
> +						        new_buildings_stop_ * 15;
> +
> +						// considering space consumers nearby
> +						prio -= bf->space_consumers_nearby_ * 5;
> +
> +					} else {  // FISH BREEDERS and GAME KEEPERS
> +						if (new_buildings_stop_ && bo.total_count() > 0)
> +							continue;
>  
>  						// especially for fish breeders
> +						if (bo.need_water_ && bf->water_nearby_ < 8)
> +							continue;
>  						if (bo.need_water_)
> -							prio = bf->water_nearby_;
> -
> -						if (bo.total_count() == 0)
> -							prio += 5;
> -
> -						if (bo.total_count() < bo.cnt_target_) {
> +							prio += bf->water_nearby_ / 5;
> +
> +						if (bo.total_count() > bo.cnt_target_)
> +							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();
> +						}
> +						if (bo.stocklevel_ > 50)
> +							continue;
> +
> +						if (bo.total_count() == 0 && gametime > 45 * 1000)
> +							prio += 100 + bf->producers_nearby_.at(bo.production_hint_) * 10;
> +						else if (bf->producers_nearby_.at(bo.production_hint_) == 0)
> +							continue;
> +						else
>  							prio += bf->producers_nearby_.at(bo.production_hint_) * 10;
> -							prio += recalc_with_border_range(*bf, prio);
>  
> -						} else if (bo.stocklevel_ < 50 && !new_buildings_stop_) {
> -							prio += bf->producers_nearby_.at(bo.production_hint_) * 5;
> -							prio += recalc_with_border_range(*bf, prio);  // only for not wood producers_
> -						} else
> -							continue;
> +						if (bf->enemy_nearby_)
> +							prio -= 10;
>  					}
>  
> -					if (prio <= 0)
> -						continue;
> -				} else if (bo.recruitment_ && gametime >
> -				           kBaseInfrastructureTime && !new_buildings_stop_) {
> +				} else if (bo.recruitment_ && !new_buildings_stop_) {
>  					// this will depend on number of mines_ and productionsites
>  					if (static_cast<int32_t>((productionsites.size() + mines_.size()) / 30) >
> -					       bo.total_count() && bo.cnt_under_construction_ ==
> -					    0)
> +					       bo.total_count() &&
> +					    bo.cnt_under_construction_ == 0)
>  						prio = 4 + bulgarian_constant;
>  				} else {  // finally normal productionsites
>  					if (bo.production_hint_ >= 0)
> @@ -1103,102 +1212,58 @@
>  					if ((bo.cnt_under_construction_ + bo.unoccupied_) > 0)
>  						continue;
>  
> -					// if hunter and too little critters nearby skipping
> -					if (bo.is_hunter_ && bf->critters_nearby_ < 5)
> -						continue;
> -					// similarly for fishers
> -					if (bo.need_water_ && bf->fish_nearby_ <= 1)
> -						continue;
> -
> -					// first eliminate buildings needing water if there is short supplies
> -					if (bo.need_water_ && bf->water_nearby_ < 4)
> -						continue;
> -
> -					if (bo.is_basic_ && bo.total_count() == 0)
> -						prio = 150 + max_preciousness;
> -					else if (bo.is_food_basic_ && game().get_gametime() >
> -					            kPrimaryFoodStartTime && bo.total_count() ==
> -					         0) {
> -						prio = 40 + max_preciousness;
> -					} else if (game().get_gametime() <
> -					           kBaseInfrastructureTime ||
> -					              new_buildings_stop_)  // leave 15 minutes for basic infrastructure only
> -						continue;
> -					else if ((bo.is_basic_ && bo.total_count() <=
> -					          1) || (output_is_needed && bo.total_count() == 0))
> -						prio = 80 + max_preciousness;
> -					else if (bo.inputs_.size() == 0) {
> -						bo.cnt_target_ =
> -						   1 + static_cast<int32_t>(mines_.size() + productionsites.size()) / 8;
> -
> -						if (bo.cnt_built_ >
> -						    bo.cnt_target_ &&
> -						       !(bo.space_consumer_ || bo.is_food_basic_))  // spaceconsumers_ and basic_s
> -							                                               // can be built more then target
> -							continue;
> -
> -						if (bo.stocklevel_time < game().get_gametime() - 5 * 1000) {
> -							bo.stocklevel_ = get_stocklevel(bo);
> -							bo.stocklevel_time = game().get_gametime();
> -						}
> -
> -						if (bo.stocklevel_ < 50) {
> -							prio = max_preciousness + bulgarian_constant;
> -
> -							if (bo.space_consumer_)  // need to consider trees nearby
> -								prio += 20 - (bf->trees_nearby_ / 3);
> -
> -							if (!bo.space_consumer_)
> -								prio -= bf->producers_nearby_.at(bo.outputs_.at(0)) *
> -								        20;  // leave some free space between them
> -
> -							if (bo.cnt_built_ < 2)
> -								prio += 5;
> -
> -							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;
> -							}
> -
> -							// hunters
> -							if (bo.is_hunter_) {
> -								prio += (bf->critters_nearby_ * 2) - 8;
> -							}
> -
> -						}
> -					} else if (!bo.inputs_.empty()) {
> -						// 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
> -						    && game().get_gametime() > 60 * 60 * 1000
> -							 && bo.desc->enhancement() != INVALID_INDEX
> -							 && !mines_.empty())
> -						{
> -							prio = max_preciousness + bulgarian_constant;
> -						}
> -						// if output is needed and there are no idle buildings
> -						else if (output_is_needed) {
> -							if (bo.cnt_built_ > 0 && bo.current_stats_ > 80) {
> -								prio = max_preciousness + bulgarian_constant + 30;
> -
> -							} else if (bo.cnt_built_ > 0 && bo.current_stats_ > 55) {
> -								prio = max_preciousness + bulgarian_constant;
> -
> -							}
> +					if (bo.forced_after_ < gametime && bo.total_count() == 0) {
> +						prio += 150;
> +					} else if (bo.cnt_built_ == 1 && game().get_gametime() > 40 * 60 * 1000 &&
> +					           bo.desc->enhancement() != INVALID_INDEX && !mines_.empty()) {
> +						prio += 10;
> +					} else if (!output_is_needed) {
> +						continue;
> +					} else if (bo.cnt_built_ == 0 && game().get_gametime() > 40 * 60 * 1000) {
> +						prio += bulgarian_constant;
> +					} else if (bo.cnt_built_ > 1 && bo.current_stats_ > 98) {
> +						prio -= bulgarian_constant * (new_buildings_stop_);
> +					} else if (new_buildings_stop_)
> +						continue;
> +
> +					// we check separatelly buildings with no inputs and some inputs
> +					if (bo.inputs_.empty()) {
> +
> +						prio += max_needed_preciousness + bulgarian_constant;
> +
> +						if (bo.space_consumer_)  // need to consider trees nearby
> +							prio += 20 - (bf->trees_nearby_ / 3);
> +
> +						// we attempt to cluster space consumers together
> +						if (bo.space_consumer_)  // need to consider trees nearby
> +							prio += bf->space_consumers_nearby_ * 2;
> +
> +						if (bo.space_consumer_ && !bf->water_nearby_)  // not close to water
> +							prio += 1;
> +
> +						if (bo.space_consumer_ &&
> +						    !bf->unowned_mines_pots_nearby_)  // not close to mountains
> +							prio += 1;
> +
> +						if (!bo.space_consumer_)
> +							prio -= bf->producers_nearby_.at(bo.outputs_.at(0)) *
> +							        20;  // leave some free space between them
> +
> +						prio -= bf->space_consumers_nearby_ * 3;
> +					}
> +
> +					if (!bo.inputs_.empty()) {
> +						if (bo.total_count() == 0)
> +							prio += max_needed_preciousness + bulgarian_constant;
> +						if (bo.cnt_built_ > 0 && bo.current_stats_ > 70) {
> +							prio += max_needed_preciousness + bulgarian_constant - 3 +
> +							        (bo.current_stats_ - 70) / 5;
>  						}
>  					}
>  
>  					if (prio <= 0)
>  						continue;
>  
> -					// then we consider borders and enemies nearby (if any)
> -					prio = recalc_with_border_range(*bf, prio);
> -
>  					//+1 if any consumers_ are nearby
>  					consumers_nearby_count = 0;
>  
> @@ -1211,33 +1276,39 @@
>  			}  // production sites done
>  			else if (bo.type == BuildingObserver::MILITARYSITE) {
>  
> -				if (new_military_buildings_stop && !bf->enemy_nearby_)
> -					continue;
> -
> -				if (near_enemy_b_buildings_stop && bf->enemy_nearby_)
> +				if (military_last_build_ > gametime - 10 * 1000)
> +					continue;
> +
> +				if (expansion_mode == kNoNewMilitary)
> +					continue;
> +
> +				if (expansion_mode == kDefenseOnly && !bf->enemy_nearby_)
> +					continue;
> +
> +				if (expansion_mode == kResourcesOrDefense &&
> +				    !(bf->enemy_nearby_ || bf->unowned_mines_pots_nearby_ || bf->stones_nearby_ ||
> +				      (water_is_important_ && bf->water_nearby_)))
>  					continue;
>  
>  				if (bf->enemy_nearby_ && bo.fighting_type_)
>  					;  // it is ok, go on
> -				else if (bf->unowned_mines_pots_nearby_ >
> -				         0 && (bo.mountain_conqueror_ || bo.expansion_type_))
> +				else if (bf->unowned_mines_pots_nearby_ > 2 &&
> +				         (bo.mountain_conqueror_ || bo.expansion_type_))
>  					;  // it is ok, go on
> -				else if (bf->unowned_land_nearby_ && bo.expansion_type_) {
> -					// decreasing probability for big buidlings
> -					if (bo.desc->get_size() == 2 && gametime % 5 >= 1)
> +				else if (bf->unowned_land_nearby_ && bo.expansion_type_ &&
> +				         num_milit_constructionsites <= 1) {
> +					;  // we allow big buildings now
> +				} else if (bf->unowned_land_nearby_ &&
> +				           bo.expansion_type_) {  // decreasing probability for big buidlings
> +					if (bo.desc->get_size() == 2 && gametime % 15 >= 1)
>  						continue;
> -					if (bo.desc->get_size() == 3 && gametime % 15 >= 1)
> +					if (bo.desc->get_size() == 3 && gametime % 40 >= 1)
>  						continue;
>  				}
>  				// it is ok, go on
>  				else
>  					continue;  // the building is not suitable for situation
>  
> -				if (bo.desc->get_size() ==
> -				    3 && game().get_gametime() <
> -				       15 * 60 * 1000)  // do not built fortresses in first half of hour of game
> -					continue;
> -
>  				if (!bf->unowned_land_nearby_)
>  					continue;
>  
> @@ -1245,17 +1316,24 @@
>  				if (!bf->enemy_nearby_ && bf->military_in_constr_nearby_ > 0)
>  					continue;
>  
> -				// here is to consider unowned potential mines
> -				int32_t mines_spots_score = 0;
> -				mines_spots_score = bf->unowned_mines_pots_nearby_;
> -
> -				if (mines_spots_score > 0) {
> -					mines_spots_score *= 4;
> -					mines_spots_score += 8;
> -				}
> -
> -				prio = (bf->unowned_land_nearby_ - 4 + mines_spots_score + bf->stones_nearby_ / 2 +
> -				        bf->military_loneliness_ / 5 - 100 + military_boost);  // * (1 + type);
> +				// a boost to prevent an expansion halt
> +				int32_t local_boost = 0;
> +				if (num_milit_constructionsites == 1)
> +					local_boost = 50;
> +				if (num_milit_constructionsites == 0)
> +					local_boost = 200;
> +
> +				// if going after resources we do not consider unowned land
> +				if (expansion_mode == kResourcesOrDefense && !bf->enemy_nearby_)
> +					prio = (bf->unowned_mines_pots_nearby_ * mines_need_intensity_ / 10
> +						+ bf->stones_nearby_ / 2 +
> +				        bf->military_loneliness_ / 5 - 100 + local_boost +
> +				        water_is_important_ * bf->water_nearby_ * water_need_intensity_ / 12);
> +				else
> +					prio = (bf->unowned_land_nearby_ - 4 + 
> +						bf->unowned_mines_pots_nearby_ * mines_need_intensity_ / 10 +
> +				        bf->stones_nearby_ / 2 + bf->military_loneliness_ / 5 - 100 + local_boost +
> +				        water_is_important_ * bf->water_nearby_  * water_need_intensity_ / 12);
>  
>  				if (bo.desc->get_size() < maxsize)
>  					prio = prio - 5;  // penalty
> @@ -1274,13 +1352,17 @@
>  				//  Militarysites are slightly important as well, to have a bigger
>  				//  chance for a warehouses (containing waiting soldiers or wares
>  				//  needed for soldier training) near the frontier.
> -				if ((static_cast<int32_t>(productionsites.size() + mines_.size())) / 35 >
> -				       static_cast<int32_t>(numof_warehouses_) && bo.cnt_under_construction_ ==
> -				    0)
> -					prio = 13;
> +				if ((static_cast<int32_t>(productionsites.size() + mines_.size()) + 20) / 35 >
> +				       static_cast<int32_t>(numof_warehouses_) &&
> +				    bo.cnt_under_construction_ == 0)
> +					prio = 20;
>  
>  				// take care about borders and enemies
> -				prio = recalc_with_border_range(*bf, prio);
> +				if (bf->enemy_nearby_)
> +					prio /= 2;
> +
> +				if (bf->unowned_land_nearby_)
> +					prio /= 2;
>  
>  				// TODO(unknown): introduce check that there is no warehouse nearby
>  				// to prevent too close placing
> @@ -1292,13 +1374,16 @@
>  					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() && bo.cnt_under_construction_ ==
> -				    0)
> -					prio = 4;
> +				if (static_cast<int32_t>((productionsites.size() + 30) / 50) > bo.total_count() &&
> +				    bo.cnt_under_construction_ == 0)
> +					prio = 4 + bulgarian_constant;
>  
>  				// take care about borders and enemies
> -				prio = recalc_with_border_range(*bf, prio);
> +				if (bf->enemy_nearby_)
> +					prio /= 2;
> +
> +				if (bf->unowned_land_nearby_)
> +					prio /= 2;
>  			}
>  
>  			// think of space consuming buildings nearby like farms or vineyards
> @@ -1332,13 +1417,13 @@
>  			for (uint32_t i = 0; i < buildings_.size() && productionsites.size() > 8; ++i) {
>  				BuildingObserver& bo = buildings_.at(i);
>  
> -				if (!bo.mines_marble_ && gametime <
> -				    kBaseInfrastructureTime)  // allow only stone mines_ in early stages of game
> -					continue;
> -
>  				if (!bo.buildable(*player_) || bo.type != BuildingObserver::MINE)
>  					continue;
>  
> +				if (bo.prohibited_till_ > gametime) {
> +					continue;
> +				}
> +
>  				if (gametime - bo.construction_decision_time_ < kBuildingMinInterval)
>  					continue;
>  
> @@ -1348,26 +1433,22 @@
>  				if ((bo.cnt_under_construction_ + bo.unoccupied_) > 0)
>  					continue;
>  
> -				// calculating actual amount of mined raw materials
> -				if (bo.stocklevel_time < game().get_gametime() - 5 * 1000) {
> -					bo.stocklevel_ = get_stocklevel(bo);
> -					bo.stocklevel_time = game().get_gametime();
> -				}
> -
> -				// Only try to build mines_ that produce needed wares.
> -				if (((bo.cnt_built_ - bo.unoccupied_) > 0 && bo.current_stats_ < 20) || bo.stocklevel_ >
> -				    40 + static_cast<uint32_t>(bo.mines_marble_) * 30) {
> -
> -					continue;
> -				}
> +				// testing if building's output is needed
> +				check_ware_needeness(
> +				   bo, &output_is_needed, &max_preciousness, &max_needed_preciousness);
> +
> +				if (!output_is_needed && bo.total_count() > 0)
> +					continue;
> +
> +				// if current one(s) are performing badly
> +				if (bo.total_count() >= 1 && bo.current_stats_ < 50)
> +					continue;
>  
>  				// this is penalty if there are existing mines too close
>  				// it is treated as multiplicator for count of near mines
>  				uint32_t nearness_penalty = 0;
>  				if ((bo.cnt_built_ + bo.cnt_under_construction_) == 0)
>  					nearness_penalty = 0;
> -				else if (bo.mines_marble_)
> -					nearness_penalty = 7;
>  				else
>  					nearness_penalty = 10;
>  
> @@ -1404,13 +1485,15 @@
>  						continue;
>  					}
>  
> +					// Prefer road side fields
> +					prio += (*j)->preferred_ ? 1 : 0;
> +
>  					if (prio > proposed_priority) {
>  						// proposed_building = bo.id;
>  						best_building = &bo;
>  						proposed_priority = prio;
>  						proposed_coords = (*j)->coords;
>  						mine = true;
> -
>  					}
>  				}  // end of evaluation of field
>  			}
> @@ -1429,22 +1512,36 @@
>  	   game().map().get_fcoords(proposed_coords), game().get_gametime() + 120000);  // two minutes
>  	blocked_fields.push_back(blocked);
>  
> -	// if space consumer we block also nearby fields
> -	if (best_building->space_consumer_ && !best_building->plants_trees_) {
> +	// we block also nearby fields
> +	// if farms and so on, for quite a long time
> +	// if military sites only for short time for AI can update information on near buildable fields
> +	if ((best_building->space_consumer_ && !best_building->plants_trees_) ||
> +	    best_building->type == BuildingObserver::MILITARYSITE) {
> +		uint32_t block_time = 0;
> +		uint32_t block_area = 0;
> +		if (best_building->space_consumer_) {
> +			block_time = 45 * 60 * 1000;
> +			block_area = 3;
> +		} else {  // militray buildings for a very short time
> +			block_time = 25 * 1000;
> +			block_area = 6;
> +		}
>  		Map& map = game().map();
>  
> -		MapRegion<Area<FCoords>> mr(map, Area<FCoords>(map.get_fcoords(proposed_coords), 3));
> +		MapRegion<Area<FCoords>> mr(map, Area<FCoords>(map.get_fcoords(proposed_coords), block_area));
>  		do {
>  			BlockedField blocked2(
> -			   map.get_fcoords(*(mr.location().field)), game().get_gametime() + 45 * 60 * 1000);
> +			   map.get_fcoords(*(mr.location().field)), game().get_gametime() + block_time);
>  			blocked_fields.push_back(blocked2);
>  		} while (mr.advance(map));
>  	}
>  
>  	if (!(best_building->type == BuildingObserver::MILITARYSITE))
>  		best_building->construction_decision_time_ = gametime;
> -	else  // very ugly hack here
> +	else {  // very ugly hack here
> +		military_last_build_ = gametime;
>  		best_building->construction_decision_time_ = gametime - kBuildingMinInterval / 2;
> +	}
>  
>  	// set the type of update that is needed
>  	if (mine) {
> @@ -1456,101 +1553,12 @@
>  	return true;
>  }
>  
> -/**
> - * This function searches for places where a new road is needed to connect two
> - * economies. It then sends the request to build the road.
> - */
> -bool DefaultAI::construct_roads(int32_t gametime) {
> -	if (economies.size() < 2) {
> -		// only one economy, no need for new roads
> -		return false;
> -	}
> -
> -	uint32_t economies_to_connect = 0;
> -	EconomyObserver* eo_to_connect = economies.front();  // dummy initialisation
> -
> -	//  fetch first two economies that might be connectable
> -	for (std::list<EconomyObserver*>::iterator i = economies.begin();
> -	     economies_to_connect < 2 && i != economies.end();
> -	     ++i)
> -
> -		//  Do not try to connect economies that already failed in last time.
> -		if ((*i)->next_connection_try <= gametime) {
> -			if (economies_to_connect == 1)
> -				eo_to_connect = *i;
> -
> -			++economies_to_connect;
> -		}
> -
> -	// No need to connect, if only one economy
> -	if (economies_to_connect < 2)
> -		return false;
> -
> -	if (eo_to_connect->flags.empty())
> -		return check_economies();
> -
> -	// Check if the flag is still there and if not care about that situation
> -	if (!eo_to_connect->flags.front()) {
> -		eo_to_connect->flags.pop_front();
> -		return check_economies();
> -	}
> -
> -	// Try to connect - this should work fine as in nearly all cases we simply
> -	// connect a constructionsite
> -	bool done = connect_flag_to_another_economy(*eo_to_connect->flags.front());
> -	eo_to_connect->flags.push_back(eo_to_connect->flags.front());
> -	eo_to_connect->flags.pop_front();
> -
> -	if (done) {
> -		eo_to_connect->failed_connection_tries = 0;
> -		return true;
> -	}
> -
> -	// If the economy consists of just one constructionsite, and the defaultAI
> -	// failed more than 4 times to connect, we remove the constructionsite
> -	if (eo_to_connect->failed_connection_tries > 3 && eo_to_connect->flags.size() == 1) {
> -		Building* bld = eo_to_connect->flags.front()->get_building();
> -
> -		if (bld) {
> -			BuildingObserver& bo = get_building_observer(bld->descr().name().c_str());
> -
> -			if (bo.type == BuildingObserver::CONSTRUCTIONSITE) {
> -				game().send_player_bulldoze(*const_cast<Flag*>(eo_to_connect->flags.front()));
> -				eo_to_connect->flags.pop_front();
> -				// Block the field at constructionsites coords for 5 minutes
> -				// against new construction tries.
> -				BlockedField blocked(
> -				   game().map().get_fcoords(bld->get_position()), game().get_gametime() + 300000);
> -				blocked_fields.push_back(blocked);
> -			}
> -		}
> -	}
> -
> -	// Unable to connect, so we let this economy wait for 30 seconds.
> -	eo_to_connect->next_connection_try = gametime + 30000;
> -	++eo_to_connect->failed_connection_tries;
> -	return false;
> -}
> -
>  // 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
> -	for (EconomyObserver* eco_obs : economies) {
> -		for (std::list<Flag const*>::iterator flag_iter = eco_obs->flags.begin();
> -			  flag_iter != eco_obs->flags.end();
> -			  ++flag_iter) {
> -			if ((*flag_iter)->is_dead_end() && (*flag_iter)->current_wares() == 0) {
> -				game().send_player_bulldoze(*const_cast<Flag*>(*flag_iter));
> -				flag_iter = eco_obs->flags.erase(flag_iter);
> -				return true;
> -			}
> -		}
> -	}
>  
> -	// force a split on roads that are longer than 3 parts
> -	// actually we do not care for loss of building capabilities - normal maps
> -	// should have enough space and the computer can expand it's territory.
> -	if (!roads.empty()) {
> +	// first force a split on roads that are longer than 3 parts
> +	// with exemption when there is too few building spots
> +	if (spots_ > 20 && !roads.empty()) {
>  		const Path& path = roads.front()->get_path();
>  
>  		if (path.get_nsteps() > 3) {
> @@ -1584,128 +1592,253 @@
>  
>  		roads.push_back(roads.front());
>  		roads.pop_front();
> -	}
> -
> -	if (!economies.empty() && inhibit_road_building_ <= gametime) {
> -		EconomyObserver* eco = economies.front();
> -
> -		if (!eco->flags.empty()) {
> -			bool finish = false;
> -			const Flag& flag = *eco->flags.front();
> -
> -			// try to connect to another economy
> -			if (economies.size() > 1)
> -				finish = connect_flag_to_another_economy(flag);
> -
> -			// try to improve the roads at this flag
> -			//  TODO(unknown): do this only on useful places - the attempt below
> -			//  unfortunatey did not work as it should...
> -			//  if the flag is full of wares or if it is not yet a fork.
> -			if (!finish)  //&& (!flag.has_capacity() || flag.nr_of_roads() < 3))
> -				finish = improve_transportation_ways(flag);
> -
> -			// cycle through flags one at a time
> -			eco->flags.push_back(eco->flags.front());
> -			eco->flags.pop_front();
> -			// and cycle through economies
> -			economies.push_back(eco);
> -			economies.pop_front();
> -			return finish;
> -		} else
> -			// If the economy has no flag, the observers need to be updated.
> -			return check_economies();
> -	}
> -
> -	return false;
> -}
> -
> -// connects a specific flag to another economy
> -bool DefaultAI::connect_flag_to_another_economy(const Flag& flag) {
> +
> +		// occasionaly we test if the road can be dismounted
> +		if (gametime % 25 == 0) {
> +			const Road& road = *roads.front();
> +			if (abundant_road_test(*const_cast<Road*>(&road))) {
> +				game().send_player_bulldoze(*const_cast<Road*>(&road));
> +				return true;
> +			}
> +		}
> +	}
> +
> +	if (inhibit_road_building_ >= gametime)
> +		return false;
> +
> +	// now we rotate economies and flags to get one flag to go on with
> +	if (economies.size() == 0)
> +		return check_economies();
> +
> +	if (economies.size() >= 2) {  // rotating economies
> +		economies.push_back(economies.front());
> +		economies.pop_front();
> +	}
> +
> +	EconomyObserver* eco = economies.front();
> +	if (eco->flags.empty())
> +		return check_economies();
> +	if (eco->flags.size() > 1) {
> +		eco->flags.push_back(eco->flags.front());
> +		eco->flags.pop_front();
> +	}
> +
> +	const Flag& flag = *eco->flags.front();
> +
> +	// now we test if it is dead end flag, if yes, destroying it
> +	if (flag.is_dead_end() && flag.current_wares() == 0) {
> +		game().send_player_bulldoze(*const_cast<Flag*>(&flag));
> +		eco->flags.pop_front();
> +		return true;
> +	}
> +
> +	// if this is end flag (or sole building) or just randomly
> +	if (flag.nr_of_roads() <= 1 || gametime % 200 == 0) {
> +		create_shortcut_road(flag, 13, 20);
> +		inhibit_road_building_ = gametime + 800;
> +	}
> +	// this is when a flag is full
> +	else if (flag.current_wares() > 6 && gametime % 10 == 0) {
> +		create_shortcut_road(flag, 9, 0);
> +		inhibit_road_building_ = gametime + 400;
> +	}
> +
> +	return false;
> +}
> +
> +// identifying roads where wares are not intensively transported
> +// and that have bypasses not much longer
> +bool DefaultAI::abundant_road_test(const Road& road) {
> +
> +	Flag& roadstartflag = road.get_flag(Road::FlagStart);
> +	Flag& roadendflag = road.get_flag(Road::FlagEnd);
> +
> +	if (roadstartflag.current_wares() > 0 || roadendflag.current_wares() > 0)
> +		return false;
> +
> +	std::priority_queue<NearFlag> queue;
> +	// only used to collect flags reachable walking over roads
> +	std::vector<NearFlag> reachableflags;
> +	queue.push(NearFlag(roadstartflag, 0, 0));
> +	uint8_t pathcounts = 0;
> +	uint8_t checkradius = 8;
> +	Map& map = game().map();
> +
> +	// algorithm to walk on roads
> +	while (!queue.empty()) {
> +
> +		// testing if we stand on the roadendflag
> +		// if is is for first time, just go on,
> +		// if second time, the goal is met, function returns true
> +		// NOCOM: what is the right way to compare the flags?

Is this still NOCOM?

> +		if (roadendflag.get_position().x == queue.top().flag->get_position().x &&
> +		    roadendflag.get_position().y == queue.top().flag->get_position().y) {
> +			pathcounts += 1;
> +			if (pathcounts > 1) {
> +				// OK, this is a second route how to get to roadendflag
> +				return true;
> +			}
> +			queue.pop();
> +			continue;
> +		}
> +
> +		std::vector<NearFlag>::iterator f =
> +		   find(reachableflags.begin(), reachableflags.end(), queue.top().flag);
> +
> +		if (f != reachableflags.end()) {
> +			queue.pop();
> +			continue;
> +		}
> +
> +		reachableflags.push_back(queue.top());
> +		queue.pop();
> +		NearFlag& nf = reachableflags.back();
> +
> +		for (uint8_t i = 1; i <= 6; ++i) {
> +			Road* const near_road = nf.flag->get_road(i);
> +
> +			if (!near_road)
> +				continue;
> +
> +			Flag* endflag = &near_road->get_flag(Road::FlagStart);
> +
> +			if (endflag == nf.flag)
> +				endflag = &near_road->get_flag(Road::FlagEnd);
> +
> +			int32_t dist = map.calc_distance(roadstartflag.get_position(), endflag->get_position());
> +
> +			if (dist > checkradius)  //  out of range of interest
> +				continue;
> +
> +			queue.push(NearFlag(*endflag, 0, dist));
> +		}
> +	}
> +	return false;
> +}
> +
> +// trying to connect the flag to another one, be it from own economy
> +// or other economy
> +bool DefaultAI::create_shortcut_road(const Flag& flag, uint16_t checkradius, uint16_t minred) {
> +
> +	// Increasing the failed_connection_tries counter
> +	// At the same time it indicates a time an economy is without a warehouse
> +	EconomyObserver* eco = get_economy_observer(flag.economy());
> +	if (flag.get_economy()->warehouses().empty()) {
> +		eco->failed_connection_tries += 1;
> +	} else {
> +		eco->failed_connection_tries = 0;
> +	}
> +
> +	// explanation for 'eco->flags.size() * eco->flags.size()'
> +	// The AI is able to dismantle whole economy without warehouse as soon as single
> +	// building not connected anywhere. But so fast dismantling is not deserved (probably)
> +	// so the bigger economy the longer it takes to be dismantled
> +	if (eco->failed_connection_tries > 3 + eco->flags.size() * eco->flags.size()) {
> +
> +		Building* bld = flag.get_building();
> +
> +		if (bld) {
> +			// first we block the field for 15 minutes, probably it is not good place to build a
> +			// building on
> +			BlockedField blocked(
> +			   game().map().get_fcoords(bld->get_position()), game().get_gametime() + 15 * 60 * 1000);
> +			blocked_fields.push_back(blocked);
> +			eco->flags.remove(&flag);
> +			game().send_player_bulldoze(*const_cast<Flag*>(&flag));
> +		}
> +		return true;
> +	}
> +
> +	Map& map = game().map();
> +
> +	// 1. first we collect all reachange points
> +	std::vector<NearFlag> nearflags;
> +	std::unordered_set<int32_t> lookuptable;
> +
>  	FindNodeWithFlagOrRoad functor;
>  	CheckStepRoadAI check(player_, MOVECAPS_WALK, true);
>  	std::vector<Coords> reachable;
> -	// first look for possible destinations
> -	functor.economy = flag.get_economy();
> -	Map& map = game().map();
> +
> +	// vector reachable now contains all suitable fields
>  	map.find_reachable_fields(
> -	   Area<FCoords>(map.get_fcoords(flag.get_position()), 16), &reachable, check, functor);
> +	   Area<FCoords>(map.get_fcoords(flag.get_position()), checkradius), &reachable, check, functor);
>  
> -	if (reachable.empty())
> +	// Does this make sense?

Turn this into a TODO comment?

> +	if (reachable.empty()) {
>  		return false;
> +	}
>  
> -	// then choose the one with the shortest path
> -	Path* path = new Path();
> -	bool found = false;
> -	check.set_openend(false);
> -	Coords closest;
>  	for (const Coords& reachable_coords : reachable) {
> -		Path* path2 = new Path();
> -
> -		if (map.findpath(flag.get_position(), reachable_coords, 0, *path2, check) >= 0) {
> -			if (!found || path->get_nsteps() > path2->get_nsteps()) {
> -				delete path;
> -				path = path2;
> -				path2 = nullptr;
> -				closest = reachable_coords;
> -				found = true;
> -			}
> -		}
> -
> -		delete path2;
> -	}
> -
> -	if (found) {
> -		// if we join a road and there is no flag yet, build one
> -		if (dynamic_cast<const Road*>(map[closest].get_immovable()))
> -			game().send_player_build_flag(player_number(), closest);
> -
> -		// and finally build the road
> -		game().send_player_build_road(player_number(), *path);
> -		return true;
> -	} else {
> -		delete path;
> -		return false;
> -	}
> -}
> -
> -// 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
> -	for (std::list<Widelands::Coords>::iterator coords_iter = flags_to_be_removed.begin();
> -		  coords_iter != flags_to_be_removed.end();
> -		  ++coords_iter) {
> -		// Maybe the flag was already removed?
> -		FCoords f = game().map().get_fcoords(*(coords_iter));
> -
> -		if (upcast(Flag, other_flag, f.field->get_immovable())) {
> -			// Check if building is dismantled, but don't waste precious wares
> -			if (!other_flag->get_building() && other_flag->current_wares() == 0) {
> -				game().send_player_bulldoze(*other_flag);
> -				flags_to_be_removed.erase(coords_iter);
> -				break;
> -			}
> -		} else {
> -			flags_to_be_removed.erase(coords_iter);
> -			break;
> -		}
> -	}
> +
> +		// first make sure there is an immovable (shold be, but still)
> +		if (upcast(PlayerImmovable const, player_immovable, map[reachable_coords].get_immovable())) {
> +
> +			// if it is the road, make a flag there
> +			if (dynamic_cast<const Road*>(map[reachable_coords].get_immovable()))
> +				game().send_player_build_flag(player_number(), reachable_coords);
> +
> +			// do not go on if it is not a flag
> +			if (!dynamic_cast<const Flag*>(map[reachable_coords].get_immovable()))
> +				continue;
> +
> +			// testing if a flag/road's economy has a warehouse, if not we are not
> +			// interested to connect to it
> +			if (player_immovable->economy().warehouses().size() == 0) {
> +				continue;
> +			}
> +
> +			// now make sure that this field has not been processed yet
> +			const int32_t hash = reachable_coords.x * 1234 + reachable_coords.y;
> +			if (lookuptable.count(hash) == 0) {
> +				lookuptable.insert(hash);
> +
> +				// adding flag into NearFlags if road is possible
> +				Path* path2 = new Path();
> +
> +				if (map.findpath(flag.get_position(), reachable_coords, 0, *path2, check) >= 0) {
> +
> +					// path is possible, but for now we presume connection
> +					//'walking on existing roads' is not possible
> +					// so we assign 'virtual distance'
> +					int32_t virtual_distance = 0;
> +					// the same economy, but connection not spotted above via "walking on roads"
> +					// algorithm
> +					if (player_immovable->get_economy() == flag.get_economy())
> +						virtual_distance = 50;
> +					else  // and now different economies
> +						virtual_distance = 100;
> +
> +					// distance as the crow flies
> +					const int32_t dist = map.calc_distance(flag.get_position(), reachable_coords);
> +
> +					nearflags.push_back(
> +					   NearFlag(*dynamic_cast<const Flag*>(map[reachable_coords].get_immovable()),
> +					            virtual_distance,
> +					            dist));
> +				}
> +				delete path2;
> +			}
> +		}
> +	}
> +
> +	// now we walk over roads and if field is reachable by roads, we change distance asigned before
>  	std::priority_queue<NearFlag> queue;
> -	std::vector<NearFlag> nearflags;
> +	std::vector<NearFlag> nearflags_tmp;  // only used to collect flags reachable walk over roads
>  	queue.push(NearFlag(flag, 0, 0));
> -	Map& map = game().map();
>  
> +	// algorithm to walk on roads
>  	while (!queue.empty()) {
>  		std::vector<NearFlag>::iterator f =
> -		   find(nearflags.begin(), nearflags.end(), queue.top().flag);
> +		   find(nearflags_tmp.begin(), nearflags_tmp.end(), queue.top().flag);
>  
> -		if (f != nearflags.end()) {
> +		if (f != nearflags_tmp.end()) {
>  			queue.pop();
>  			continue;
>  		}
>  
> -		nearflags.push_back(queue.top());
> +		nearflags_tmp.push_back(queue.top());
>  		queue.pop();
> -		NearFlag& nf = nearflags.back();
> +		NearFlag& nf = nearflags_tmp.back();
>  
>  		for (uint8_t i = 1; i <= 6; ++i) {
>  			Road* const road = nf.flag->get_road(i);
> @@ -1720,32 +1853,87 @@
>  
>  			int32_t dist = map.calc_distance(flag.get_position(), endflag->get_position());
>  
> -			if (dist > 12)  //  out of range
> +			if (dist > checkradius)  //  out of range of interest
>  				continue;
>  
>  			queue.push(NearFlag(*endflag, nf.cost_ + road->get_path().get_nsteps(), dist));
>  		}
>  	}
>  
> -	std::sort(nearflags.begin(), nearflags.end(), CompareDistance());
> -	CheckStepRoadAI check(player_, MOVECAPS_WALK, false);
> -
> -	for (uint32_t i = 1; i < nearflags.size(); ++i) {
> +	// iterating over nearflags_tmp, each item in nearflags_tmp should be contained also in nearflags
> +	// so for each corresponding field in nearflags we update "cost" (distance on existing roads)
> +	// to actual value
> +	for (std::vector<NearFlag>::iterator nf_walk_it = nearflags_tmp.begin();
> +	     nf_walk_it != nearflags_tmp.end();
> +	     ++nf_walk_it) {
> +		int32_t const hash_walk =
> +		   nf_walk_it->flag->get_position().x * 1234 + nf_walk_it->flag->get_position().y;
> +		if (lookuptable.count(hash_walk) > 0) {
> +			// iterting over nearflags
> +			for (std::vector<NearFlag>::iterator nf_it = nearflags.begin(); nf_it != nearflags.end();
> +			     ++nf_it) {
> +				int32_t const hash =
> +				   nf_it->flag->get_position().x * 1234 + nf_it->flag->get_position().y;
> +				if (hash == hash_walk) {
> +					// decreasing "cost" (of walking via roads)
> +					if (nf_it->cost_ > nf_walk_it->cost_) {
> +						nf_it->cost_ = nf_walk_it->cost_;
> +					}
> +				}
> +			}
> +		}
> +	}
> +
> +	// ordering nearflags
> +	std::sort(nearflags.begin(), nearflags.end(), CompareShortening());
> +
> +	// this is just a random number, will be used later
> +	int32_t random_gametime = game().get_gametime();
> +
> +	// the problem here is that send_player_build_road() does not return succes/failed
> +	// if it did, we would just test the first nearflag, then go on with further flags until
> +	// a road is built or nearflags are exhausted
> +	// but now we must just randomly pick one of nearflags
> +	// probabililty of picking decreases with position in nearflags
> +	for (uint32_t i = 0; i < nearflags.size() && i < 10; ++i) {
>  		NearFlag& nf = nearflags.at(i);
>  
> -		if (2 * nf.distance_ + 2 < nf.cost_) {
> +		// terminating looping if reduction is too low (nearflags are sorted by reduction)
> +		if ((nf.cost_ - nf.distance_) < minred) {
> +			return false;
> +		}
> +
> +		// testing the nearflag
> +		// usually we allow connecting only if both flags are closer then 'checkradius-2'
> +		// with exeption the flag belongs to a small economy (typically a new building not connected
> +		// yet)
> +		if ((nf.cost_ - nf.distance_) >= minred && nf.distance_ >= 2 &&
> +		    nf.distance_ < checkradius - 2) {
> +
> +			// sometimes the shortest road is not the buildable, even if map.findpath claims so
> +			// best so we add some randomness
> +			random_gametime /= 3;
> +			if (random_gametime % 3 > 1) {
> +				continue;
> +			}
> +
>  			Path& path = *new Path();
>  
> -			if (map.findpath(flag.get_position(), nf.flag->get_position(), 0, path, check) >=
> -			    0 && static_cast<int32_t>(2 * path.get_nsteps() + 2) < nf.cost_) {
> -				game().send_player_build_road(player_number(), path);
> -				return true;
> +			// value of pathcost is not important, it just indicates, that the path can be built
> +			const int32_t pathcost =
> +			   map.findpath(flag.get_position(), nf.flag->get_position(), 0, path, check);
> +
> +			if (pathcost >= 0) {
> +				if (static_cast<int32_t>(nf.cost_ - path.get_nsteps()) > minred) {
> +					game().send_player_build_road(player_number(), path);
> +					return true;
> +				}
>  			}
> -
>  			delete &path;
>  		}
>  	}
>  
> +	// if all possible roads skipped
>  	return false;
>  }
>  
> @@ -1763,8 +1951,8 @@
>  	}
>  
>  	for (std::list<EconomyObserver*>::iterator obs_iter = economies.begin();
> -		  obs_iter != economies.end();
> -		  ++obs_iter) {
> +	     obs_iter != economies.end();
> +	     ++obs_iter) {
>  		// check if any flag has changed its economy
>  		std::list<Flag const*>& fl = (*obs_iter)->flags;
>  
> @@ -1812,10 +2000,15 @@
>  		site.unoccupied_till_ = game().get_gametime();
>  	}
>  
> +	// do not dismantle or upgrade the same type of building too soon - to give some time to update
> +	// statistics
> +	if (site.bo->last_dismantle_time_ > game().get_gametime() - 30 * 1000)
> +		return false;
> +
>  	// Get max radius of recursive workarea
>  	WorkareaInfo::size_type radius = 0;
>  	const WorkareaInfo& workarea_info = site.bo->desc->m_workarea_info;
> -	for (const std::pair<uint32_t, std::set<std::string> > & temp_info : workarea_info) {
> +	for (const std::pair<uint32_t, std::set<std::string>>& temp_info : workarea_info) {
>  		if (radius < temp_info.first) {
>  			radius = temp_info.first;
>  		}
> @@ -1823,54 +2016,128 @@
>  
>  	Map& map = game().map();
>  
> -	// 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 (site.bo->last_dismantle_time_ > game().get_gametime() - 30 * 1000)
> -		return false;
> +	// first we try to upgrade
> +	// Upgrading policy
> +	// a) if there are two buildings and none enhanced and there are workers
> +	// available, one is to be enhanced
> +	// b) if there are two buildings
> +	// statistics percents are decisive
> +	const BuildingIndex enhancement = site.site->descr().enhancement();
> +	if (enhancement != INVALID_INDEX && (site.bo->cnt_built_ - site.bo->unoccupied_) > 1) {
> +
> +		BuildingIndex enbld = INVALID_INDEX;  // to get rid of this
> +		BuildingObserver* bestbld = nullptr;
> +
> +		// Only enhance buildings that are allowed (scenario mode)
> +		// do not do decisions to fast
> +		if (player_->is_building_type_allowed(enhancement)) {
> +
> +			const BuildingDescr& bld = *tribe_->get_building_descr(enhancement);
> +			BuildingObserver& en_bo = get_building_observer(bld.name().c_str());
> +
> +			if (gametime - en_bo.construction_decision_time_ >= kBuildingMinInterval &&
> +			    (en_bo.cnt_under_construction_ + en_bo.unoccupied_) == 0) {
> +
> +				// don't upgrade without workers
> +				if (site.site->has_workers(enhancement, game())) {
> +
> +					// forcing first upgrade
> +					if (en_bo.cnt_built_ == 0 && !mines_.empty()) {
> +						enbld = enhancement;
> +						bestbld = &en_bo;
> +					}
> +
> +					// if the decision was not made yet, consider normal upgrade
> +					if (enbld == INVALID_INDEX) {
> +						// compare the performance %
> +						if (static_cast<int32_t>(en_bo.current_stats_) -
> +						       static_cast<int32_t>(site.bo->current_stats_) >
> +						    20) {
> +
> +							enbld = enhancement;
> +							bestbld = &en_bo;
> +						}
> +					}
> +				}
> +			}
> +
> +			// Enhance if enhanced building is useful
> +			// additional: we dont want to lose the old building
> +			if (enbld != INVALID_INDEX) {
> +				game().send_player_enhance_building(*site.site, enbld);
> +				bestbld->construction_decision_time_ = gametime;
> +
> +				return true;
> +			}
> +		}
> +	}
>  
>  	// Lumberjack / Woodcutter handling
>  	if (site.bo->need_trees_) {
> -		if (map.find_immovables(Area<FCoords>(map.get_fcoords(site.site->get_position()), radius),
> -		                        nullptr,
> -										FindImmovableAttribute(MapObjectDescr::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 (site.bo->cnt_built_ <=
> -			    3 + static_cast<int32_t>(mines_.size() + productionsites.size()) / 20) {
> -
> -				return false;
> -			}
> -
> -			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");
> -				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;
> -			}
> -			return false;
> -		}
> -		return false;
> +
> +		// Do not destruct the last few lumberjacks
> +		if (site.bo->cnt_built_ <= site.bo->cnt_target_) {
> +			return false;
> +		}
> +
> +		if (site.site->get_statistics_percent() > 20)
> +			return false;
> +
> +		const uint32_t remaining_trees =
> +		   map.find_immovables(Area<FCoords>(map.get_fcoords(site.site->get_position()), radius),
> +		                       nullptr,
> +		                       FindImmovableAttribute(MapObjectDescr::get_attribute_id("tree")));
> +
> +		// do not dismantle if there are some trees remaining
> +		if (remaining_trees > 5)
> +			return false;
> +
> +		if (site.bo->stocklevel_time < game().get_gametime() - 10 * 1000) {
> +			site.bo->stocklevel_ = get_stocklevel(*site.bo);
> +			site.bo->stocklevel_time = game().get_gametime();
> +		}
> +
> +		// if we need wood badly
> +		if (remaining_trees > 0 && site.bo->stocklevel_ <= 50)
> +			return false;
> +
> +		// so finally we dismantle the lumberjac

lumberjack

> +		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;
>  	}
>  
>  	// Wells handling
>  	if (site.bo->mines_water_) {
> -		if (site.unoccupied_till_ + 6 * 60 * 1000 < game().get_gametime()
> -		                                            && site.site->get_statistics_percent() ==
> -		    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 (site.unoccupied_till_ + 6 * 60 * 1000 < game().get_gametime() &&
> +		    site.site->get_statistics_percent() == 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;
> +		}
> +
> +		// do not consider dismantling if we are under target
> +		if (site.bo->last_dismantle_time_ + 90 * 1000 > game().get_gametime())
> +			return false;
> +
> +		// now we test the stocklevel and dismantle the well if we have enough water
> +		// but first we make sure we do not dismantle a well too soon
> +		// after dismantling previous one
> +		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 (site.bo->stocklevel_ > 250) {  // dismantle
> +			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;
> +		}
> +
>  		return false;
>  	}
>  
> @@ -1880,7 +2147,8 @@
>  		if (map.find_immovables(
>  		       Area<FCoords>(map.get_fcoords(site.site->get_position()), radius),
>  		       nullptr,
> -				 FindImmovableAttribute(MapObjectDescr::get_attribute_id("granite"))) == 0) {
> +
> +		       FindImmovableAttribute(MapObjectDescr::get_attribute_id("granite"))) == 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.
> @@ -1889,9 +2157,8 @@
>  			return true;
>  		}
>  
> -		if (site.unoccupied_till_ + 6 * 60 * 1000 < game().get_gametime()
> -		                                            && site.site->get_statistics_percent() ==
> -		    0) {
> +		if (site.unoccupied_till_ + 6 * 60 * 1000 < game().get_gametime() &&
> +		    site.site->get_statistics_percent() == 0) {
>  			// it is possible that there are stones but quary is not able to mine them
>  			site.bo->last_dismantle_time_ = game().get_gametime();
>  			flags_to_be_removed.push_back(site.site->base_flag().get_position());
> @@ -1905,13 +2172,14 @@
>  
>  	// All other SPACE_CONSUMERS without input and above target_count
>  	if (site.bo->inputs_.empty()  // does not consume anything
> -	    && site.bo->production_hint_ ==
> -	    -1  // not a renewing building (forester...)
> -	          && site.unoccupied_till_ +
> -	          10 * 60 * 1000 <
> -	       game().get_gametime()               // > 10 minutes old
> -	       && site.site->can_start_working()  // building is occupied
> -	       && site.bo->space_consumer_ && !site.bo->plants_trees_) {
> +	    &&
> +	    site.bo->production_hint_ == -1  // not a renewing building (forester...)
> +	    &&
> +	    site.unoccupied_till_ + 10 * 60 * 1000 < game().get_gametime()  // > 10 minutes old
> +	    &&
> +	    site.site->can_start_working()  // building is occupied
> +	    &&
> +	    site.bo->space_consumer_ && !site.bo->plants_trees_) {
>  
>  		// if we have more buildings then target
>  		if (site.bo->cnt_built_ > site.bo->cnt_target_) {
> @@ -1920,8 +2188,8 @@
>  				site.bo->stocklevel_time = game().get_gametime();
>  			}
>  
> -			if (site.site->get_statistics_percent()<
> -			       30 && site.bo->stocklevel_> 100) {  // production stats == 0%
> +			if (site.site->get_statistics_percent() < 30 &&
> +			    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);
> @@ -1929,8 +2197,8 @@
>  			}
>  		}
>  
> -		// regardless of count of sites a building can be dismanteld if it performs too bad
> -		if (site.site->get_statistics_percent() <= 10) {
> +		// a building can be dismanteld if it performs too bad, if it is not the last one

dismantled

> +		if (site.site->get_statistics_percent() <= 10 && site.bo->cnt_built_ > 1) {
>  
>  			flags_to_be_removed.push_back(site.site->base_flag().get_position());
>  			game().send_player_dismantle(*site.site);
> @@ -1941,12 +2209,11 @@
>  	}
>  
>  	// buildings with inputs_, checking if we can a dismantle some due to low performance
> -	if (!site.bo->inputs_.empty() && (site.bo->cnt_built_ - site.bo->unoccupied_) >=
> -	    3 && site.site->can_start_working() && site.site->get_statistics_percent() <
> -	    20 &&                             // statistics for the building
> -	       site.bo->current_stats_<30 &&  // overall statistics
> -	                               (game().get_gametime() - site.unoccupied_till_)> 10 *
> -	       60 * 1000) {
> +	if (!site.bo->inputs_.empty() && (site.bo->cnt_built_ - site.bo->unoccupied_) >= 3 &&
> +	    site.site->can_start_working() &&
> +	    site.site->get_statistics_percent() < 20 &&  // statistics for the building
> +	    site.bo->current_stats_ < 30 &&              // overall statistics
> +	    (game().get_gametime() - site.unoccupied_till_) > 10 * 60 * 1000) {
>  
>  		site.bo->last_dismantle_time_ = game().get_gametime();
>  		flags_to_be_removed.push_back(site.site->base_flag().get_position());
> @@ -1956,13 +2223,11 @@
>  
>  	// 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 (site.bo->inputs_.size() ==
> -	    0 && site.bo->production_hint_ <
> -	       0 && site.site->can_start_working()
> -	       && !site.bo->space_consumer_ && site.site->get_statistics_percent() <
> -	       10 && ((game().get_gametime() - site.built_time_) > 10 * 60 * 1000)) {
> +	if (site.bo->inputs_.size() == 0 && site.bo->production_hint_ < 0 &&
> +	    site.site->can_start_working() && !site.bo->space_consumer_ &&
> +	    site.site->get_statistics_percent() < 10 &&
> +	    ((game().get_gametime() - site.built_time_) > 10 * 60 * 1000)) {
>  
>  		site.bo->last_dismantle_time_ = game().get_gametime();
>  		flags_to_be_removed.push_back(site.site->base_flag().get_position());
> @@ -1981,8 +2246,7 @@
>  
>  		uint16_t score = site.bo->stocklevel_;
>  
> -
> -		if (score > 150 && site.bo->cnt_built_ > site.bo->cnt_target_) {
> +		if (score > 200 && site.bo->cnt_built_ > site.bo->cnt_target_) {
>  
>  			site.bo->last_dismantle_time_ = game().get_gametime();
>  			flags_to_be_removed.push_back(site.site->base_flag().get_position());
> @@ -1990,82 +2254,15 @@
>  			return true;
>  		}
>  
> -		if (score > 70 && !site.site->is_stopped()) {
> -
> -			game().send_player_start_stop_building(*site.site);
> -		}
> -
> -		if (score < 50 && site.site->is_stopped()) {
> -
> -			game().send_player_start_stop_building(*site.site);
> -		}
> -	}
> -
> -	// Upgrading policy
> -	// a) if there are two buildings and none enhanced, one is enhanced
> -	// b) if there are two buildings and at least one functional
> -	// statistics percents are decisive
> -
> -	// do not upgrade if current building is only one in operation
> -	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.
> -	const BuildingIndex enhancement = site.site->descr().enhancement();
> -	BuildingIndex enbld = INVALID_INDEX;  // to get rid of this
> -	BuildingObserver* bestbld = nullptr;
> -
> -	// Only enhance buildings that are allowed (scenario mode)
> -	if (player_->is_building_type_allowed(enhancement)) {
> -		const BuildingDescr& bld = *tribe_->get_building_descr(enhancement);
> -		BuildingObserver& en_bo = get_building_observer(bld.name().c_str());
> -
> -		// do not build the same building so soon (kind of duplicity check)
> -		if (gametime - en_bo.construction_decision_time_ >= kBuildingMinInterval)
> -			{
> -			// Don't enhance this building, if there is already one of same type
> -			// under construction or unoccupied_
> -			if (en_bo.cnt_under_construction_ + en_bo.unoccupied_ <= 0)
> -				{
> -				// don't upgrade without workers
> -				if (site.site->has_workers(enhancement, game()))
> -					{
> -					// forcing first upgrade
> -					if ((en_bo.cnt_under_construction_ + en_bo.cnt_built_ + en_bo.unoccupied_) == 0
> -						&& (site.bo->cnt_built_ - site.bo->unoccupied_) >= 1
> -						&& (game().get_gametime() - site.unoccupied_till_) > 30 * 60 * 1000
> -						&& !mines_.empty())
> -					{
> -						game().send_player_enhance_building(*site.site, enhancement);
> -						return true;
> -					}
> -				}
> -			}
> -		}
> -
> -		// now, let consider normal upgrade
> -		// do not upgrade if candidate production % is too low
> -		if ((en_bo.cnt_built_ - en_bo.unoccupied_) != 0
> -			|| (en_bo.cnt_under_construction_ + en_bo.unoccupied_) <= 0
> -			|| en_bo.current_stats_ >= 50) {
> -
> -			if (en_bo.current_stats_ > 65
> -				&& ((en_bo.current_stats_ - site.bo->current_stats_) + // priority for enhancement
> -					(en_bo.current_stats_ - 65)) > 0)
> -			{
> -				enbld = enhancement;
> -				bestbld = &en_bo;
> -			}
> -		}
> -	}
> -
> -	// Enhance if enhanced building is useful
> -	// additional: we dont want to lose the old building
> -	if (enbld != INVALID_INDEX) {
> -		game().send_player_enhance_building(*site.site, enbld);
> -		bestbld->construction_decision_time_ = gametime;
> -		changed = true;
> +		if (score > 120 && !site.site->is_stopped()) {
> +
> +			game().send_player_start_stop_building(*site.site);
> +		}
> +
> +		if (score < 80 && site.site->is_stopped()) {
> +
> +			game().send_player_start_stop_building(*site.site);
> +		}
>  	}
>  
>  	return changed;
> @@ -2081,82 +2278,72 @@
>  	if ((next_mine_check_due_ > gametime) || mines_.empty())
>  		return false;
>  
> -	next_mine_check_due_ = gametime + 10000;  // 10 seconds is enough
> +	next_mine_check_due_ = gametime + 7000;  // 7 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& site = mines_.front();
> -	Map& map = game().map();
> -	Field* field = map.get_fcoords(site.site->get_position()).field;
>  
> -	// first get rid of mines that are missing workers for some time (5 minutes)
> +	// first get rid of mines that are missing workers for some time (6 minutes),
>  	// released worker (if any) can be usefull elsewhere !
> -	if (site.built_time_ + 5 * 60 * 1000 < gametime && !site.site->can_start_working()) {
> -		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 (site.site->get_statistics_percent() > 40)
> -		return false;
> -
> -	// Check if mine ran out of resources
> -	uint8_t current = field->get_resources_amount();
> -
> -	if (current < 1) {
> -		// 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(site.site->base_flag().get_position());
> -		game().send_player_dismantle(*site.site);
> -
> -		return true;
> -	}
> +	if (site.built_time_ + 6 * 60 * 1000 < gametime && !site.site->can_start_working()) {
> +		flags_to_be_removed.push_back(site.site->base_flag().get_position());
> +		game().send_player_dismantle(*site.site);
> +		return true;
> +	}
> +
> +	// doing nothing when failed count is too low
> +	if (site.no_resources_count < 6)
> +		return false;
> +
> +	// dismantling when the failed count is too high
> +	if (site.no_resources_count > 14) {
> +		flags_to_be_removed.push_back(site.site->base_flag().get_position());
> +		game().send_player_dismantle(*site.site);
> +		site.bo->construction_decision_time_ = gametime;
> +		return true;
> +	}
> +
> +	// updating statistics if needed
> +	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();
> +	}
> +
> +	// if we have enough of mined resources on stock - do not upgrade
> +	if (site.bo->stocklevel_ > 150)
> +		return false;
>  
>  	// Check whether building is enhanceable. If yes consider an upgrade.
>  	const BuildingIndex enhancement = site.site->descr().enhancement();
> -	BuildingIndex enbld = INVALID_INDEX;
> -	BuildingObserver* bestbld = nullptr;
> +
> +	// if no enhancement is possible
> +	if (enhancement == INVALID_INDEX) {
> +		// will be destroyed when no_resource_count will overflow
> +		return false;
> +	}
> +
>  	bool changed = false;
> -	// Only enhance buildings that are allowed (scenario mode)
>  	if (player_->is_building_type_allowed(enhancement)) {
>  		// first exclude possibility there are enhancements in construction or unoccupied_
>  		const BuildingDescr& bld = *tribe_->get_building_descr(enhancement);
>  		BuildingObserver& en_bo = get_building_observer(bld.name().c_str());
>  
> -		if (en_bo.unoccupied_ + en_bo.cnt_under_construction_ <= 0)
> -		{
> -		// do not upgrade target building are not working properly (probably do not have food)
> -			if (en_bo.cnt_built_ <= 0 && en_bo.current_stats_ >= 60)
> -			{
> -				// do not build the same building so soon (kind of duplicity check)
> -				if (gametime - en_bo.construction_decision_time_ >= kBuildingMinInterval)
> -				{
> -					// Check if mine needs an enhancement to mine more resources
> -					uint8_t const until =
> -					field->get_starting_res_amount() * (100 - site.bo->mines_percent_) / 100;
> +		// if it is too soon for enhancement and making sure there are no unoccupied mines
> +		if (gametime - en_bo.construction_decision_time_ >= kBuildingMinInterval &&
> +		    en_bo.unoccupied_ + en_bo.cnt_under_construction_ == 0) {
>  
> -					if (until >= current) {
> -							enbld = enhancement;
> -							bestbld = &en_bo;
> -					}
> -				}
> +			// now verify that there are enough workers
> +			if (site.site->has_workers(enhancement, game())) {  // enhancing
> +				game().send_player_enhance_building(*site.site, enhancement);
> +				en_bo.construction_decision_time_ = gametime;
> +				changed = true;
>  			}
>  		}
>  	}
>  
> -	// Enhance if enhanced building is useful and possible
> -	if (enbld != INVALID_INDEX) {
> -		game().send_player_enhance_building(*site.site, enbld);
> -		bestbld->construction_decision_time_ = gametime;
> -		changed = true;
> -
> -	}
> -
>  	return changed;
>  }
>  
> @@ -2175,9 +2362,43 @@
>  	return count;
>  }
>  
> -// this count all stock for all output
> +// calculating how much an output is needed
> +// 'max' is because the building can have more outputs
> +void DefaultAI::check_ware_needeness(BuildingObserver& bo,
> +                                     bool* output_is_needed,
> +                                     int16_t* max_preciousness,
> +                                     int16_t* max_needed_preciousness) {
> +
> +	// reseting values

resetting values

> +	*output_is_needed = false;
> +	*max_preciousness = 0;
> +	*max_needed_preciousness = 0;
> +
> +	for (EconomyObserver* observer : economies) {
> +		// Don't check if the economy has no warehouse.
> +		if (observer->economy.warehouses().empty())
> +			continue;
> +
> +		for (uint32_t m = 0; m < bo.outputs_.size(); ++m) {
> +			WareIndex wt(static_cast<size_t>(bo.outputs_.at(m)));
> +
> +			if (observer->economy.needs_ware(wt)) {
> +				*output_is_needed = true;
> +
> +				if (wares.at(bo.outputs_.at(m)).preciousness_ > *max_needed_preciousness)
> +					*max_needed_preciousness = wares.at(bo.outputs_.at(m)).preciousness_;
> +			}
> +
> +			if (wares.at(bo.outputs_.at(m)).preciousness_ > *max_preciousness)
> +				*max_preciousness = wares.at(bo.outputs_.at(m)).preciousness_;
> +		}
> +	}
> +}
> +
> +// counts produced output on stock
> +// if multiple outputs, it returns lowest value
>  uint32_t DefaultAI::get_stocklevel(BuildingObserver& bo) {
> -	uint32_t count = 0;
> +	uint32_t count = 10000;
>  
>  	if (!bo.outputs_.empty()) {
>  		for (EconomyObserver* observer : economies) {
> @@ -2187,7 +2408,8 @@
>  
>  			for (uint32_t m = 0; m < bo.outputs_.size(); ++m) {
>  				WareIndex wt(static_cast<size_t>(bo.outputs_.at(m)));
> -				count += observer->economy.stock_ware(wt);
> +				if (count > observer->economy.stock_ware(wt))
> +					count = observer->economy.stock_ware(wt);
>  			}
>  		}
>  	}
> @@ -2219,16 +2441,6 @@
>  		if (it->site->stationed_soldiers().size() == 0)
>  			unstationed_milit_buildings_ += 1;
>  
> -	// count militarysites in construction
> -	military_under_constr_ = 0;
> -
> -	for (uint32_t j = 0; j < buildings_.size(); ++j) {
> -		BuildingObserver& bo = buildings_.at(j);
> -
> -		if (bo.type == BuildingObserver::MILITARYSITE)
> -			military_under_constr_ += bo.cnt_under_construction_;
> -	}
> -
>  	// Only useable, if defaultAI owns at least one militarysite
>  	if (militarysites.empty())
>  		return false;
> @@ -2239,16 +2451,15 @@
>  	MilitarySite* ms = militarysites.front().site;
>  	uint32_t const vision = ms->descr().vision_range();
>  	FCoords f = map.get_fcoords(ms->get_position());
> -	// look if there is any enemy land nearby
> -	// FindNodeEnemy find_enemy(player, game());
> -	// look if there is any enemies building
> +	// look if there are any enemies building
>  	FindNodeEnemiesBuilding find_enemy(player_, game());
>  
>  	// 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 (map.find_fields(Area<FCoords>(f, vision + 4), 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.
> +
>  		if (ms->economy().warehouses().size()) {
>  			uint32_t const j = ms->soldier_capacity();
>  
> @@ -2266,9 +2477,15 @@
>  				update_buildable_field(bf, vision, true);
>  				const int32_t size_penalty = ms->get_size() - 1;
>  
> -				if (bf.military_capacity_ > 9 && bf.military_presence_ >
> -				    3 && bf.military_loneliness_<160 && bf.military_stationed_>(2 + size_penalty)) {
> +				int16_t score = 0;
> +				score += (bf.military_capacity_ > 5);
> +				score += (bf.military_presence_ > 3);
> +				score += (bf.military_loneliness_ < 180);
> +				score += (bf.military_stationed_ > (2 + size_penalty));
> +				score -= (ms->soldier_capacity() * 2 > static_cast<uint32_t>(bf.military_capacity_));
> +				score += (bf.unowned_land_nearby_ < 10);
>  
> +				if (score >= 4) {
>  					if (ms->get_playercaps() & Widelands::Building::PCap_Dismantle) {
>  						flags_to_be_removed.push_back(ms->base_flag().get_position());
>  						game().send_player_dismantle(*ms);
> @@ -2281,19 +2498,22 @@
>  			}
>  		}
>  	} else {
> +
>  		// If an enemy is in sight and the number of stationed soldier is not
>  		// at maximum - set it to maximum.
>  		uint32_t const j = ms->max_soldier_capacity();
>  		uint32_t const k = ms->soldier_capacity();
>  
> -		if (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);
> -
> -		changed = true;
> +		if (j > k) {
> +			game().send_player_change_soldier_capacity(*ms, j - k);
> +			changed = true;
> +		}
> +
> +		// and also set preference to Heroes
> +		if (MilitarySite::kPrefersHeroes != ms->get_soldier_preference()) {
> +			game().send_player_militarysite_set_soldier_preference(*ms, MilitarySite::kPrefersHeroes);
> +			changed = true;
> +		}
>  	}
>  
>  	// reorder:;
> @@ -2388,7 +2608,8 @@
>  void DefaultAI::consider_productionsite_influence(BuildableField& field,
>                                                    Coords coords,
>                                                    const BuildingObserver& bo) {
> -	if (bo.space_consumer_ && game().map().calc_distance(coords, field.coords) < 4)
> +	if (bo.space_consumer_ && !bo.plants_trees_ &&
> +	    game().map().calc_distance(coords, field.coords) < 8)
>  		++field.space_consumers_nearby_;
>  
>  	for (size_t i = 0; i < bo.inputs_.size(); ++i)
> @@ -2437,8 +2658,8 @@
>  	else if (upcast(Flag const, flag, &pi)) {
>  		for (EconomyObserver* eco_obs : economies) {
>  			for (std::list<Flag const*>::iterator flag_iter = eco_obs->flags.begin();
> -				  flag_iter != eco_obs->flags.end();
> -				  ++flag_iter) {
> +			     flag_iter != eco_obs->flags.end();
> +			     ++flag_iter) {
>  				if (*flag_iter == flag) {
>  					eco_obs->flags.erase(flag_iter);
>  					return;
> @@ -2446,8 +2667,8 @@
>  			}
>  		}
>  		for (std::list<Flag const*>::iterator flag_iter = new_flags.begin();
> -			  flag_iter != new_flags.end();
> -			  ++flag_iter) {
> +		     flag_iter != new_flags.end();
> +		     ++flag_iter) {
>  			if (*flag_iter == flag) {
>  				new_flags.erase(flag_iter);
>  				return;
> @@ -2457,6 +2678,17 @@
>  		roads.remove(road);
>  }
>  
> +// this is called when a mine reports "out of resources"
> +void DefaultAI::out_of_resources_site(const ProductionSite& site) {
> +
> +	// we must identify which mine matches the productionsite a note reffers to
> +	for (std::list<ProductionSiteObserver>::iterator i = mines_.begin(); i != mines_.end(); ++i)
> +		if (i->site == &site) {
> +			i->no_resources_count += 1;
> +			break;
> +		}
> +}
> +
>  // this is called whenever we gain a new building
>  void DefaultAI::gain_building(Building& b) {
>  	BuildingObserver& bo = get_building_observer(b.descr().name().c_str());
> @@ -2466,6 +2698,11 @@
>  		   get_building_observer(ref_cast<ConstructionSite, Building>(b).building().name().c_str());
>  		++target_bo.cnt_under_construction_;
>  		++num_constructionsites_;
> +		if (target_bo.type == BuildingObserver::PRODUCTIONSITE)
> +			++num_prod_constructionsites;
> +		if (target_bo.type == BuildingObserver::MILITARYSITE)
> +			++num_milit_constructionsites;
> +
>  		// Let defaultAI try to directly connect the constructionsite
>  		next_road_due_ = game().get_gametime();
>  	} else {
> @@ -2478,6 +2715,7 @@
>  			productionsites.back().built_time_ = game().get_gametime();
>  			productionsites.back().unoccupied_till_ = game().get_gametime();
>  			productionsites.back().stats_zero_ = 0;
> +			productionsites.back().no_resources_count = 0;
>  
>  			for (uint32_t i = 0; i < bo.outputs_.size(); ++i)
>  				++wares.at(bo.outputs_.at(i)).producers_;
> @@ -2501,6 +2739,7 @@
>  			militarysites.back().bo = &bo;
>  			militarysites.back().checks = bo.desc->get_size();
>  			militarysites.back().enemies_nearby = true;
> +
>  		} else if (bo.type == BuildingObserver::WAREHOUSE)
>  			++numof_warehouses_;
>  	}
> @@ -2515,6 +2754,11 @@
>  		   ref_cast<ConstructionSite const, Building const>(b).building().name().c_str());
>  		--target_bo.cnt_under_construction_;
>  		--num_constructionsites_;
> +		if (target_bo.type == BuildingObserver::PRODUCTIONSITE)
> +			--num_prod_constructionsites;
> +		if (target_bo.type == BuildingObserver::MILITARYSITE)
> +			--num_milit_constructionsites;
> +
>  	} else {
>  		--bo.cnt_built_;
>  
> @@ -2547,6 +2791,7 @@
>  			for (uint32_t i = 0; i < bo.inputs_.size(); ++i)
>  				--wares.at(bo.inputs_.at(i)).consumers_;
>  		} else if (bo.type == BuildingObserver::MILITARYSITE) {
> +
>  			for (std::list<MilitarySiteObserver>::iterator i = militarysites.begin();
>  			     i != militarysites.end();
>  			     ++i)
> @@ -2574,9 +2819,9 @@
>  	for (const int16_t& temp_inputs : bo.inputs_) {
>  		for (const BuildingObserver& temp_building : buildings_) {
>  			if (temp_building.cnt_built_ &&
> -				 std::find(temp_building.outputs_.begin(), temp_building.outputs_.end(), temp_inputs) !=
> -					 temp_building.outputs_.end() &&
> -				 check_supply(temp_building)) {
> +			    std::find(temp_building.outputs_.begin(), temp_building.outputs_.end(), temp_inputs) !=
> +			       temp_building.outputs_.end() &&
> +			    check_supply(temp_building)) {
>  				++supplied;
>  				break;
>  			}
> @@ -2637,7 +2882,6 @@
>  		} else {
>  			player_attackable[j - 1] = false;
>  		}
> -
>  	}
>  
>  	if (!any_attackable) {
> @@ -2650,8 +2894,9 @@
>  	const uint16_t attempts = militarysites.size() / 6 + 1;
>  	Map& map = game().map();
>  
> +	uint16_t position = 0;
>  	for (uint32_t i = 0; i < attempts && !any_attacked; ++i) {
> -		const uint16_t position = (game().get_gametime() + (3 * i)) % militarysites.size();
> +		position = (game().get_gametime() + (3 * i)) % militarysites.size();
>  
>  		// picking random military sites
>  		// using gametime as a random value, but it is constant so each next is on position +3
> @@ -2670,7 +2915,6 @@
>  		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 (!mso->enemies_nearby && gametime % 8 > 0) {
> @@ -2777,3 +3021,31 @@
>  		return false;
>  	}
>  }
> +
> +// This is used for profiling, so usually this is not used :)
> +void DefaultAI::print_land_stats() {
> +	// this will just print statistics of land size
> +	// intended for AI development only
> +	uint32_t plr_in_game = 0;
> +	uint32_t sum_l = 0;
> +	uint32_t count_l = 0;
> +	uint32_t sum_m = 0;
> +	uint32_t count_m = 0;
> +	PlayerNumber const nr_players = game().map().get_nrplayers();
> +	iterate_players_existing_novar(p, nr_players, game())++ plr_in_game;
> +	const Game::GeneralStatsVector& genstats = game().get_general_statistics();
> +
> +	for (uint8_t j = 1; j <= plr_in_game; ++j) {
> +		log(" player: %1d, landsize: %5d, military strength: %3d\n",
> +		    j,
> +		    genstats[j - 1].land_size.back(),
> +		    genstats[j - 1].miltary_strength.back());
> +
> +		sum_l += genstats[j - 1].land_size.back();
> +		count_l += 1;
> +		sum_m += genstats[j - 1].miltary_strength.back();
> +		count_m += 1;
> +	}
> +
> +	log(" Average: Landsize: %5d, military strenght: %3d\n", sum_l / count_l, sum_m / count_m);
> +}
> 
> === modified file 'src/ai/defaultai.h'
> --- src/ai/defaultai.h	2014-09-10 13:03:40 +0000
> +++ src/ai/defaultai.h	2014-10-03 21:34:06 +0000
> @@ -123,13 +123,20 @@
>  
>  	void update_productionsite_stats(int32_t);
>  
> +	void check_ware_needeness(BuildingObserver& bo,
> +	                          bool* output_is_needed,
> +	                          int16_t* max_preciousness,
> +	                          int16_t* max_needed_preciousness);
> +
>  	bool construct_building(int32_t);
> -	bool construct_roads(int32_t);
> +
> +	// all road management is invoked by function improve_roads()
> +	// if needed it calls create_shortcut_road() with a flag from which
> +	// new road should be considered (or is needed)
>  	bool improve_roads(int32_t);
> -
> -	bool improve_transportation_ways(const Widelands::Flag&);
> -	bool connect_flag_to_another_economy(const Widelands::Flag&);
> -
> +	bool create_shortcut_road(const Widelands::Flag&, uint16_t maxcheckradius, uint16_t minred);
> +	// trying to identify roads that might be removed
> +	bool abundant_road_test(const Widelands::Road&);
>  	bool check_economies();
>  	bool check_productionsites(int32_t);
>  	bool check_mines_(int32_t);
> @@ -152,11 +159,14 @@
>  	void lose_immovable(const Widelands::PlayerImmovable&);
>  	void gain_building(Widelands::Building&);
>  	void lose_building(const Widelands::Building&);
> +	void out_of_resources_site(const Widelands::ProductionSite&);
>  
>  	bool check_supply(const BuildingObserver&);
>  
>  	bool consider_attack(int32_t);
>  
> +	void print_land_stats();
> +
>  private:
>  	// Variables of default AI
>  	uint8_t type_;
> @@ -169,6 +179,8 @@
>  
>  	std::vector<BuildingObserver> buildings_;
>  	uint32_t num_constructionsites_;
> +	uint32_t num_milit_constructionsites;
> +	uint32_t num_prod_constructionsites;
>  
>  	std::list<Widelands::FCoords> unusable_fields;
>  	std::list<BuildableField*> buildable_fields;
> @@ -193,22 +205,32 @@
>  	int32_t next_militarysite_check_due_;
>  	int32_t next_attack_consideration_due_;
>  	int32_t next_helpersites_check_due_;
> +	int32_t next_bf_check_due_;
>  	int32_t inhibit_road_building_;
>  	int32_t time_of_last_construction_;
> -	int32_t next_wood_cutting_check_due_;
> +	int32_t enemy_last_seen_;
>  
>  	uint16_t numof_warehouses_;
>  
>  	bool new_buildings_stop_;
> +	bool water_is_important_;				//for atlanteans, water is on pair with mines and so on
> +	uint16_t mines_need_intensity_;			// when we have enough mines weight of possible mines spots
> +											// is decreased (range 0-10)
> +	uint16_t water_need_intensity_;			// when we have enough fishers weight of water nearby
> +											// is decreased (range 0-5)
>  	uint16_t unstationed_milit_buildings_;  // counts empty military buildings (ones where no soldier
>  	                                        // is belogning to)
>  	uint16_t military_under_constr_;
>  	uint16_t military_last_dismantle_;
>  	int32_t military_last_build_;  // sometimes expansions just stops, this is time of last military
>  	                               // building build
> +	int32_t spots_;                // sum of buildable fields
>  
> -	std::unique_ptr<Notifications::Subscriber<Widelands::NoteFieldPossession>> field_possession_subscriber_;
> +	std::unique_ptr<Notifications::Subscriber<Widelands::NoteFieldPossession>>
> +	   field_possession_subscriber_;
>  	std::unique_ptr<Notifications::Subscriber<Widelands::NoteImmovable>> immovable_subscriber_;
> +	std::unique_ptr<Notifications::Subscriber<Widelands::NoteProductionSiteOutOfResources>>
> +	   outofresource_subscriber_;
>  };
>  
>  #endif  // end of include guard: WL_AI_DEFAULTAI_H
> 
> === modified file 'src/logic/productionsite.cc'
> --- src/logic/productionsite.cc	2014-09-10 18:56:42 +0000
> +++ src/logic/productionsite.cc	2014-10-03 21:34:06 +0000
> @@ -912,6 +912,7 @@
>  
>  void ProductionSite::notify_player(Game & game, uint8_t minutes)
>  {
> +
>  	if (m_out_of_resource_delay_counter >=
>  		 descr().out_of_resource_delay_attempts()) {
>  		if (descr().out_of_resource_title().empty())
> @@ -930,6 +931,10 @@
>  				 true,
>  				 minutes * 60000, 0);
>  		}
> +		// following sends "out of resources" messages to be picked up by AI
> +		// used as a information for dismantling and upgrading mines
> +		if (descr().get_ismine())
> +			Notifications::publish(NoteProductionSiteOutOfResources(this, get_owner()));
>  	}
>  	if (m_out_of_resource_delay_counter++ >=
>  		 descr().out_of_resource_delay_attempts()) {
> 
> === modified file 'src/logic/productionsite.h'
> --- src/logic/productionsite.h	2014-09-19 12:54:54 +0000
> +++ src/logic/productionsite.h	2014-10-03 21:34:06 +0000
> @@ -155,6 +155,7 @@
>  	uint8_t get_statistics_percent() {return m_last_stat_percent;}
>  	uint8_t get_crude_statistics() {return (m_crude_percent + 5000) / 10000;}
>  
> +
>  	const std::string& production_result() const {return m_production_result;}
>  
>  	 // Production and worker programs set this to explain the current
> @@ -303,6 +304,24 @@
>  	uint8_t    m_max;
>  };
>  
> +/**
> + * Note to be published when a production site is out of resources
> + */
> +// A note we're using to notify the AI
> +struct NoteProductionSiteOutOfResources {
> +	CAN_BE_SEND_AS_NOTE(NoteId::ProductionSiteOutOfResources)
> +
> +	// The production site that is out of resources.
> +	ProductionSite* ps;
> +
> +	// The player that owns the production site.
> +	Player * player;
> +
> +	NoteProductionSiteOutOfResources(ProductionSite* const init_ps, Player* init_player)
> +		: ps(init_ps), player(init_player) {
> +	}
> +};
> +
>  }
>  
>  #endif  // end of include guard: WL_LOGIC_PRODUCTIONSITE_H
> 
> === modified file 'src/notifications/note_ids.h'
> --- src/notifications/note_ids.h	2014-07-16 07:44:33 +0000
> +++ src/notifications/note_ids.h	2014-10-03 21:34:06 +0000
> @@ -31,6 +31,7 @@
>  	Immovable,
>  	FieldPossession,
>  	FieldTransformed,
> +	ProductionSiteOutOfResources,
>  };
>  
>  #endif  // end of include guard: WL_NOTIFICATIONS_NOTE_IDS_H
> 
> === modified file 'tribes/atlanteans/armorsmithy/conf'
> --- tribes/atlanteans/armorsmithy/conf	2014-07-27 19:31:34 +0000
> +++ tribes/atlanteans/armorsmithy/conf	2014-10-03 21:34:06 +0000
> @@ -3,7 +3,7 @@
>  output=steel_shield
>  
>  [aihints]
> -build_material=false
> +prohibited_till=900
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/atlanteans/bakery/conf'
> --- tribes/atlanteans/bakery/conf	2014-07-27 19:31:34 +0000
> +++ tribes/atlanteans/bakery/conf	2014-10-03 21:34:06 +0000
> @@ -2,8 +2,8 @@
>  output=bread
>  
>  [aihints]
> -build_material=false
> -is_food_basic=true
> +forced_after=1200
> +prohibited_till=900
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/atlanteans/blackroot_farm/conf'
> --- tribes/atlanteans/blackroot_farm/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/blackroot_farm/conf	2014-10-03 21:34:06 +0000
> @@ -2,8 +2,8 @@
>  output=blackroot
>  
>  [aihints]
> +prohibited_till=600
>  space_consumer=true
> -build_material=false
>  
>  [buildcost]
>  planks=3
> 
> === modified file 'tribes/atlanteans/castle/conf'
> --- tribes/atlanteans/castle/conf	2014-07-28 12:48:04 +0000
> +++ tribes/atlanteans/castle/conf	2014-10-03 21:34:06 +0000
> @@ -13,6 +13,7 @@
>  expansion=true
>  fighting=true
>  mountain_conqueror=true
> +prohibited_till=1800
>  
>  [buildcost]
>  planks=4
> 
> === modified file 'tribes/atlanteans/charcoal_kiln/conf'
> --- tribes/atlanteans/charcoal_kiln/conf	2014-08-26 17:25:00 +0000
> +++ tribes/atlanteans/charcoal_kiln/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=coal
>  
>  [aihints]
> -build_material=false
> +prohibited_till=1200
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/atlanteans/coalmine/conf'
> --- tribes/atlanteans/coalmine/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/coalmine/conf	2014-10-03 21:34:06 +0000
> @@ -3,6 +3,7 @@
>  
>  [aihints]
>  mines=coal
> +prohibited_till=1200
>  
>  [buildcost]
>  log=7
> 
> === modified file 'tribes/atlanteans/cornflour/conf'
> --- tribes/atlanteans/cornflour/conf	2014-07-28 14:04:36 +0000
> +++ tribes/atlanteans/cornflour/conf	2014-10-03 21:34:06 +0000
> @@ -1,7 +1,7 @@
>  help=_Cornflour is produced in a mill out of corn and is one of three parts of the Atlantean bread produced in bakeries.
>  
>  default_target_quantity=15
> -preciousness=2
> +preciousness=7
>  
>  [idle]
>  pics=idle.png
> 
> === modified file 'tribes/atlanteans/crystalmine/conf'
> --- tribes/atlanteans/crystalmine/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/crystalmine/conf	2014-10-03 21:34:06 +0000
> @@ -5,6 +5,7 @@
>  
>  [aihints]
>  mines=granite
> +prohibited_till=600
>  
>  [buildcost]
>  log=7
> 
> === modified file 'tribes/atlanteans/farm/conf'
> --- tribes/atlanteans/farm/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/farm/conf	2014-10-03 21:34:06 +0000
> @@ -3,8 +3,9 @@
>  
>  [aihints]
>  space_consumer=true
> -is_basic=true # farm needs spidercloth to be build and spidercloth needs
> +forced_after=180 # farm needs spidercloth to be build and spidercloth needs
>                # corn for production -> farm should be build ASAP!
> +prohibited_till=120
>  
>  [buildcost]
>  log=3
> 
> === modified file 'tribes/atlanteans/fish_breeders_house/conf'
> --- tribes/atlanteans/fish_breeders_house/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/fish_breeders_house/conf	2014-10-03 21:34:06 +0000
> @@ -1,9 +1,9 @@
>  size=small
>  
>  [aihints]
> -build_material=false
>  needs_water=true
>  renews_map_resource=fish
> +prohibited_till=900
>  
>  [buildcost]
>  log=1
> 
> === modified file 'tribes/atlanteans/fishers_house/conf'
> --- tribes/atlanteans/fishers_house/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/fishers_house/conf	2014-10-03 21:34:06 +0000
> @@ -2,8 +2,8 @@
>  output=fish
>  
>  [aihints]
> -build_material=false
>  needs_water=true
> +prohibited_till=600
>  
>  [buildcost]
>  log=1
> 
> === modified file 'tribes/atlanteans/foresters_house/conf'
> --- tribes/atlanteans/foresters_house/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/foresters_house/conf	2014-10-03 21:34:06 +0000
> @@ -3,6 +3,7 @@
>  [aihints]
>  space_consumer=true
>  renews_map_resource=log
> +prohibited_till=50
>  
>  [buildcost]
>  log=1
> 
> === modified file 'tribes/atlanteans/gold-spinning-mill/conf'
> --- tribes/atlanteans/gold-spinning-mill/conf	2014-07-27 19:31:34 +0000
> +++ tribes/atlanteans/gold-spinning-mill/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=goldyarn
>  
>  [aihints]
> -build_material=false
> +prohibited_till=600
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/atlanteans/goldmine/conf'
> --- tribes/atlanteans/goldmine/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/goldmine/conf	2014-10-03 21:34:06 +0000
> @@ -2,8 +2,8 @@
>  output=goldore
>  
>  [aihints]
> -build_material=false
>  mines=gold
> +prohibited_till=1200
>  
>  [buildcost]
>  log=7
> 
> === modified file 'tribes/atlanteans/horsefarm/conf'
> --- tribes/atlanteans/horsefarm/conf	2014-07-27 19:31:34 +0000
> +++ tribes/atlanteans/horsefarm/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,6 @@
>  output=horse
>  
>  [aihints]
> -build_material=false
>  recruitment=true
>  
>  [buildcost]
> 
> === modified file 'tribes/atlanteans/hunters_house/conf'
> --- tribes/atlanteans/hunters_house/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/hunters_house/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=meat
>  
>  [aihints]
> -build_material=false
> +prohibited_till=60
>  
>  [buildcost]
>  log=1
> 
> === modified file 'tribes/atlanteans/ironmine/conf'
> --- tribes/atlanteans/ironmine/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/ironmine/conf	2014-10-03 21:34:06 +0000
> @@ -2,8 +2,8 @@
>  output=ironore
>  
>  [aihints]
> -build_material=false
>  mines=iron
> +prohibited_till=1200
>  
>  [buildcost]
>  log=7
> 
> === modified file 'tribes/atlanteans/labyrinth/conf'
> --- tribes/atlanteans/labyrinth/conf	2014-09-30 08:05:35 +0000
> +++ tribes/atlanteans/labyrinth/conf	2014-10-03 21:34:06 +0000
> @@ -97,3 +97,6 @@
>  [idle]
>  pics=labyrinth_i_??.png  # ???
>  hotspot=80 88
> +
> +[aihints]
> +prohibited_till=2700
> 
> === modified file 'tribes/atlanteans/mill/conf'
> --- tribes/atlanteans/mill/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/mill/conf	2014-10-03 21:34:06 +0000
> @@ -3,7 +3,7 @@
>  output=blackrootflour
>  
>  [aihints]
> -build_material=false
> +prohibited_till=600
>  
>  [buildcost]
>  log=3
> 
> === modified file 'tribes/atlanteans/quarry/conf'
> --- tribes/atlanteans/quarry/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/quarry/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=stone
>  
>  [aihints]
> -is_basic=true
> +forced_after=60
>  stoneproducer=true
>  
>  [buildcost]
> 
> === modified file 'tribes/atlanteans/sawmill/conf'
> --- tribes/atlanteans/sawmill/conf	2014-07-27 19:31:34 +0000
> +++ tribes/atlanteans/sawmill/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,8 @@
>  output=planks
>  
>  [aihints]
> -is_basic=true
> +forced_after=300
> +prohibited_till=60
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/atlanteans/scouts_house/conf'
> --- tribes/atlanteans/scouts_house/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/scouts_house/conf	2014-10-03 21:34:06 +0000
> @@ -1,7 +1,6 @@
>  size=small
>  
>  [aihints]
> -build_material=false
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/atlanteans/shipyard/conf'
> --- tribes/atlanteans/shipyard/conf	2014-09-30 08:05:35 +0000
> +++ tribes/atlanteans/shipyard/conf	2014-10-03 21:34:06 +0000
> @@ -1,7 +1,6 @@
>  size=medium
>  
>  [aihints]
> -build_material=false
>  needs_water=true
>  
>  [buildcost]
> 
> === modified file 'tribes/atlanteans/smelting_works/conf'
> --- tribes/atlanteans/smelting_works/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/smelting_works/conf	2014-10-03 21:34:06 +0000
> @@ -3,7 +3,7 @@
>  output=gold
>  
>  [aihints]
> -build_material=false
> +prohibited_till=600
>  
>  [buildcost]
>  log=1
> 
> === modified file 'tribes/atlanteans/smokery/conf'
> --- tribes/atlanteans/smokery/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/smokery/conf	2014-10-03 21:34:06 +0000
> @@ -3,8 +3,8 @@
>  output=smoked_fish
>  
>  [aihints]
> -build_material=false
> -is_food_basic=true
> +forced_after=900
> +prohibited_till=60
>  
>  [buildcost]
>  log=1
> 
> === modified file 'tribes/atlanteans/spidercloth/conf'
> --- tribes/atlanteans/spidercloth/conf	2014-07-28 14:04:36 +0000
> +++ tribes/atlanteans/spidercloth/conf	2014-10-03 21:34:06 +0000
> @@ -1,7 +1,7 @@
>  help=_Spidercloth is made out of spideryarn in a weaving mill. It is used in the toolsmithy and the shipyard. Also some higher developed buildings need spidercloth for their construction.
>  
>  default_target_quantity=20
> -preciousness=1
> +preciousness=5
>  
>  [idle]
>  pics=idle.png
> 
> === modified file 'tribes/atlanteans/spiderfarm/conf'
> --- tribes/atlanteans/spiderfarm/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/spiderfarm/conf	2014-10-03 21:34:06 +0000
> @@ -35,3 +35,7 @@
>  [working]
>  pics=spiderfarm_i_??.png  # ???
>  hotspot=87 75
> +
> +[aihints]
> +forced_after=60
> +prohibited_till=60
> 
> === modified file 'tribes/atlanteans/spideryarn/conf'
> --- tribes/atlanteans/spideryarn/conf	2014-04-08 06:28:45 +0000
> +++ tribes/atlanteans/spideryarn/conf	2014-10-03 21:34:06 +0000
> @@ -1,7 +1,7 @@
>  help=_This yarn is produced by spiders, which are bred by spider farms. It is processed into spidercloth in a weaving mill.
>  
>  default_target_quantity=10
> -preciousness=2
> +preciousness=11
>  
>  [idle]
>  pics=idle.png
> 
> === modified file 'tribes/atlanteans/toolsmithy/conf'
> --- tribes/atlanteans/toolsmithy/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/toolsmithy/conf	2014-10-03 21:34:06 +0000
> @@ -13,8 +13,8 @@
>  output=shovel
>  
>  [aihints]
> -build_material=false
> -is_basic=true
> +forced_after=900
> +prohibited_till=450
>  
>  [buildcost]
>  log=1
> 
> === modified file 'tribes/atlanteans/tower/conf'
> --- tribes/atlanteans/tower/conf	2014-07-28 12:48:04 +0000
> +++ tribes/atlanteans/tower/conf	2014-10-03 21:34:06 +0000
> @@ -14,6 +14,7 @@
>  [aihints]
>  expansion=true
>  mountain_conqueror=true
> +prohibited_till=600
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/atlanteans/weaponsmithy/conf'
> --- tribes/atlanteans/weaponsmithy/conf	2014-07-27 19:31:34 +0000
> +++ tribes/atlanteans/weaponsmithy/conf	2014-10-03 21:34:06 +0000
> @@ -6,7 +6,7 @@
>  output=heavy_double_trident
>  
>  [aihints]
> -build_material=false
> +prohibited_till=900
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/atlanteans/weaving-mill/conf'
> --- tribes/atlanteans/weaving-mill/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/weaving-mill/conf	2014-10-03 21:34:06 +0000
> @@ -4,7 +4,8 @@
>  output=golden_tabard
>  
>  [aihints]
> -is_basic=true
> +forced_after=60
> +prohibited_till=60
>  
>  [buildcost]
>  log=3
> 
> === modified file 'tribes/atlanteans/well/conf'
> --- tribes/atlanteans/well/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/well/conf	2014-10-03 21:34:06 +0000
> @@ -3,6 +3,8 @@
>  
>  [aihints]
>  mines_water=true
> +forced_after=600
> +prohibited_till=300
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/atlanteans/woodcutters_house/conf'
> --- tribes/atlanteans/woodcutters_house/conf	2014-07-29 09:27:08 +0000
> +++ tribes/atlanteans/woodcutters_house/conf	2014-10-03 21:34:06 +0000
> @@ -2,8 +2,8 @@
>  output=log
>  
>  [aihints]
> -is_basic=true
>  logproducer=true
> +forced_after=0
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/barbarians/axfactory/conf'
> --- tribes/barbarians/axfactory/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/axfactory/conf	2014-10-03 21:34:06 +0000
> @@ -7,7 +7,6 @@
>  enhancement=warmill
>  
>  [aihints]
> -build_material=false
>  
>  [enhancement_cost]
>  log=1
> 
> === modified file 'tribes/barbarians/bakery/conf'
> --- tribes/barbarians/bakery/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/bakery/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=pittabread
>  
>  [aihints]
> -build_material=false
> +prohibited_till=600
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/barbarians/cattlefarm/conf'
> --- tribes/barbarians/cattlefarm/conf	2014-07-27 19:32:24 +0000
> +++ tribes/barbarians/cattlefarm/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,6 @@
>  output=ox
>  
>  [aihints]
> -build_material=false
>  recruitment=true
>  
>  [buildcost]
> 
> === modified file 'tribes/barbarians/charcoal_kiln/conf'
> --- tribes/barbarians/charcoal_kiln/conf	2014-08-26 17:25:00 +0000
> +++ tribes/barbarians/charcoal_kiln/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=coal
>  
>  [aihints]
> -build_material=false
> +prohibited_till=900
>  
>  [buildcost]
>  log=3
> 
> === modified file 'tribes/barbarians/coalmine/conf'
> --- tribes/barbarians/coalmine/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/coalmine/conf	2014-10-03 21:34:06 +0000
> @@ -5,6 +5,7 @@
>  [aihints]
>  mines=coal
>  mines_percent=30
> +prohibited_till=1200
>  
>  [buildcost]
>  log=4
> 
> === modified file 'tribes/barbarians/donjon/conf'
> --- tribes/barbarians/donjon/conf	2014-07-28 12:48:04 +0000
> +++ tribes/barbarians/donjon/conf	2014-10-03 21:34:06 +0000
> @@ -14,6 +14,7 @@
>  expansion=true
>  fighting=true
>  mountain_conqueror=true
> +prohibited_till=1500
>  
>  [buildcost]
>  blackwood=7
> 
> === modified file 'tribes/barbarians/fishers_hut/conf'
> --- tribes/barbarians/fishers_hut/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/fishers_hut/conf	2014-10-03 21:34:06 +0000
> @@ -2,8 +2,8 @@
>  output=fish
>  
>  [aihints]
> -build_material=false
>  needs_water=true
> +prohibited_till=900
>  
>  [buildcost]
>  log=4
> 
> === modified file 'tribes/barbarians/fortress/conf'
> --- tribes/barbarians/fortress/conf	2014-07-28 12:48:04 +0000
> +++ tribes/barbarians/fortress/conf	2014-10-03 21:34:06 +0000
> @@ -14,6 +14,7 @@
>  expansion=true
>  fighting=true
>  mountain_conqueror=true
> +prohibited_till=1800
>  
>  [buildcost]
>  blackwood=9
> 
> === modified file 'tribes/barbarians/gamekeepers_hut/conf'
> --- tribes/barbarians/gamekeepers_hut/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/gamekeepers_hut/conf	2014-10-03 21:34:06 +0000
> @@ -1,8 +1,8 @@
>  size=small
>  
>  [aihints]
> -build_material=false
>  renews_map_resource=meat
> +prohibited_till=900
>  
>  [buildcost]
>  log=4
> 
> === modified file 'tribes/barbarians/goldmine/conf'
> --- tribes/barbarians/goldmine/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/goldmine/conf	2014-10-03 21:34:06 +0000
> @@ -3,9 +3,9 @@
>  enhancement=deep_goldmine
>  
>  [aihints]
> -build_material=false
>  mines=gold
>  mines_percent=30
> +prohibited_till=1200
>  
>  [buildcost]
>  log=4
> 
> === modified file 'tribes/barbarians/granitemine/conf'
> --- tribes/barbarians/granitemine/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/granitemine/conf	2014-10-03 21:34:06 +0000
> @@ -3,6 +3,7 @@
>  
>  [aihints]
>  mines=granite
> +prohibited_till=900
>  
>  [buildcost]
>  log=4
> 
> === modified file 'tribes/barbarians/hardener/conf'
> --- tribes/barbarians/hardener/conf	2014-07-27 19:32:24 +0000
> +++ tribes/barbarians/hardener/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=blackwood
>  
>  [aihints]
> -is_basic=true
> +forced_after=0
>  
>  [buildcost]
>  log=3
> 
> === modified file 'tribes/barbarians/helmsmithy/conf'
> --- tribes/barbarians/helmsmithy/conf	2014-07-27 19:32:24 +0000
> +++ tribes/barbarians/helmsmithy/conf	2014-10-03 21:34:06 +0000
> @@ -4,7 +4,7 @@
>  output=warhelm
>  
>  [aihints]
> -build_material=false
> +prohibited_till=1200
>  
>  [buildcost]
>  log=3
> 
> === modified file 'tribes/barbarians/hunters_hut/conf'
> --- tribes/barbarians/hunters_hut/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/hunters_hut/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=meat
>  
>  [aihints]
> -build_material=false
> +prohibited_till=300
>  
>  [buildcost]
>  log=4
> 
> === modified file 'tribes/barbarians/lumberjacks_hut/conf'
> --- tribes/barbarians/lumberjacks_hut/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/lumberjacks_hut/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=log
>  
>  [aihints]
> -is_basic=true
> +forced_after=0
>  logproducer=true
>  
>  [buildcost]
> 
> === modified file 'tribes/barbarians/metalworks/conf'
> --- tribes/barbarians/metalworks/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/metalworks/conf	2014-10-03 21:34:06 +0000
> @@ -12,8 +12,8 @@
>  enhancement=axfactory
>  
>  [aihints]
> -build_material=false
> -is_basic=true
> +forced_after=300
> +prohibited_till=120
>  
>  [buildcost]
>  log=1
> 
> === modified file 'tribes/barbarians/micro-brewery/conf'
> --- tribes/barbarians/micro-brewery/conf	2014-07-27 19:32:24 +0000
> +++ tribes/barbarians/micro-brewery/conf	2014-10-03 21:34:06 +0000
> @@ -3,7 +3,7 @@
>  enhancement=brewery
>  
>  [aihints]
> -build_material=false
> +forced_after=500
>  
>  [buildcost]
>  log=3
> 
> === modified file 'tribes/barbarians/oremine/conf'
> --- tribes/barbarians/oremine/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/oremine/conf	2014-10-03 21:34:06 +0000
> @@ -3,8 +3,8 @@
>  enhancement=deep_oremine
>  
>  [aihints]
> -build_material=false
>  mines=iron
> +prohibited_till=1200
>  mines_percent=30
>  
>  [buildcost]
> 
> === modified file 'tribes/barbarians/quarry/conf'
> --- tribes/barbarians/quarry/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/quarry/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=raw_stone
>  
>  [aihints]
> -is_basic=true
> +forced_after=0
>  stoneproducer=true
>  
>  [buildcost]
> 
> === modified file 'tribes/barbarians/reed_yard/conf'
> --- tribes/barbarians/reed_yard/conf	2014-07-27 19:32:24 +0000
> +++ tribes/barbarians/reed_yard/conf	2014-10-03 21:34:06 +0000
> @@ -3,6 +3,7 @@
>  
>  [aihints]
>  space_consumer=true
> +forced_after=0
>  
>  [buildcost]
>  log=5
> 
> === modified file 'tribes/barbarians/scouts_hut/conf'
> --- tribes/barbarians/scouts_hut/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/scouts_hut/conf	2014-10-03 21:34:06 +0000
> @@ -1,7 +1,6 @@
>  size=small
>  
>  [aihints]
> -build_material=false
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/barbarians/shipyard/conf'
> --- tribes/barbarians/shipyard/conf	2014-09-30 08:05:35 +0000
> +++ tribes/barbarians/shipyard/conf	2014-10-03 21:34:06 +0000
> @@ -1,7 +1,6 @@
>  size=medium
>  
>  [aihints]
> -build_material=false
>  needs_water=true
>  
>  [buildcost]
> 
> === modified file 'tribes/barbarians/smelting_works/conf'
> --- tribes/barbarians/smelting_works/conf	2014-07-27 19:32:24 +0000
> +++ tribes/barbarians/smelting_works/conf	2014-10-03 21:34:06 +0000
> @@ -3,7 +3,7 @@
>  output=gold
>  
>  [aihints]
> -build_material=false
> +prohibited_till=300
>  
>  [buildcost]
>  log=3
> 
> === modified file 'tribes/barbarians/tavern/conf'
> --- tribes/barbarians/tavern/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/tavern/conf	2014-10-03 21:34:06 +0000
> @@ -3,8 +3,7 @@
>  enhancement=inn
>  
>  [aihints]
> -build_material=false
> -is_food_basic=true
> +forced_after=900
>  
>  [buildcost]
>  log=3
> 
> === modified file 'tribes/barbarians/trainingcamp/conf'
> --- tribes/barbarians/trainingcamp/conf	2014-08-26 17:25:00 +0000
> +++ tribes/barbarians/trainingcamp/conf	2014-10-03 21:34:06 +0000
> @@ -35,6 +35,9 @@
>  min_level=0
>  max_level=4
>  
> +[aihints]
> +prohibited_till=2700
> +
>  [soldier hp]
>  min_level=0
>  max_level=2
> 
> === modified file 'tribes/barbarians/warmill/conf'
> --- tribes/barbarians/warmill/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/warmill/conf	2014-10-03 21:34:06 +0000
> @@ -9,7 +9,6 @@
>  enhanced_building=yes
>  
>  [aihints]
> -build_material=false
>  
>  [enhancement_cost]
>  log=1
> 
> === modified file 'tribes/barbarians/weaving-mill/conf'
> --- tribes/barbarians/weaving-mill/conf	2014-07-27 19:32:24 +0000
> +++ tribes/barbarians/weaving-mill/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=cloth
>  
>  [aihints]
> -build_material=false
> +prohibited_till=1200
>  
>  [buildcost]
>  log=5
> 
> === modified file 'tribes/barbarians/well/conf'
> --- tribes/barbarians/well/conf	2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/well/conf	2014-10-03 21:34:06 +0000
> @@ -2,8 +2,8 @@
>  output=water
>  
>  [aihints]
> -build_material=false
>  mines_water=true
> +prohibited_till=600
>  
>  [buildcost]
>  log=4
> 
> === modified file 'tribes/empire/armorsmithy/conf'
> --- tribes/empire/armorsmithy/conf	2014-07-27 19:32:24 +0000
> +++ tribes/empire/armorsmithy/conf	2014-10-03 21:34:06 +0000
> @@ -5,7 +5,7 @@
>  output=plate_armor
>  
>  [aihints]
> -build_material=false
> +prohibited_till=900
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/empire/bakery/conf'
> --- tribes/empire/bakery/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/bakery/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=bread
>  
>  [aihints]
> -build_material=false
> +prohibited_till=600
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/empire/beer/conf'
> --- tribes/empire/beer/conf	2013-07-23 19:04:12 +0000
> +++ tribes/empire/beer/conf	2014-10-03 21:34:06 +0000
> @@ -1,7 +1,7 @@
>  help=_This beer is produced in a brewery out of wheat and water. It is consumed by miners in coal and iron ore mines.
>  
>  default_target_quantity=15
> -preciousness=2
> +preciousness=5
>  
>  [idle]
>  pics=idle.png
> 
> === modified file 'tribes/empire/brewery/conf'
> --- tribes/empire/brewery/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/brewery/conf	2014-10-03 21:34:06 +0000
> @@ -2,8 +2,8 @@
>  output=beer
>  
>  [aihints]
> -build_material=false
> -is_food_basic=true
> +forced_after=900
> +prohibited_till=600
>  
>  [buildcost]
>  log=1
> 
> === modified file 'tribes/empire/charcoal_kiln/conf'
> --- tribes/empire/charcoal_kiln/conf	2014-08-26 17:25:00 +0000
> +++ tribes/empire/charcoal_kiln/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=coal
>  
>  [aihints]
> -build_material=false
> +prohibited_till=600
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/empire/coalmine/conf'
> --- tribes/empire/coalmine/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/coalmine/conf	2014-10-03 21:34:06 +0000
> @@ -5,6 +5,7 @@
>  [aihints]
>  mines=coal
>  mines_percent=50
> +prohibited_till=1200
>  
>  [buildcost]
>  log=4
> 
> === modified file 'tribes/empire/donkeyfarm/conf'
> --- tribes/empire/donkeyfarm/conf	2014-07-27 19:32:24 +0000
> +++ tribes/empire/donkeyfarm/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,6 @@
>  output=donkey
>  
>  [aihints]
> -build_material=false
>  recruitment=true
>  
>  [buildcost]
> 
> === modified file 'tribes/empire/farm/conf'
> --- tribes/empire/farm/conf	2014-07-27 19:32:24 +0000
> +++ tribes/empire/farm/conf	2014-10-03 21:34:06 +0000
> @@ -3,7 +3,7 @@
>  
>  [aihints]
>  space_consumer=true
> -is_food_basic=true
> +forced_after=900
>  
>  [buildcost]
>  wood=2
> 
> === modified file 'tribes/empire/fishers_house/conf'
> --- tribes/empire/fishers_house/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/fishers_house/conf	2014-10-03 21:34:06 +0000
> @@ -2,8 +2,8 @@
>  output=fish
>  
>  [aihints]
> -build_material=false
>  needs_water=true
> +prohibited_till=600
>  
>  [buildcost]
>  log=1
> 
> === modified file 'tribes/empire/flour/conf'
> --- tribes/empire/flour/conf	2013-07-23 19:04:12 +0000
> +++ tribes/empire/flour/conf	2014-10-03 21:34:06 +0000
> @@ -1,7 +1,7 @@
>  help=_Flour is produced by the mill out of wheat and is needed in the bakery to produce the tasty Empire bread.
>  
>  default_target_quantity=20
> -preciousness=3
> +preciousness=5
>  
>  [idle]
>  pics=flour_idle.png
> 
> === modified file 'tribes/empire/fortress/conf'
> --- tribes/empire/fortress/conf	2014-07-28 12:48:04 +0000
> +++ tribes/empire/fortress/conf	2014-10-03 21:34:06 +0000
> @@ -14,6 +14,7 @@
>  expansion=true
>  fighting=true
>  mountain_conqueror=true
> +prohibited_till=1500
>  
>  [buildcost]
>  wood=5
> 
> === modified file 'tribes/empire/goldmine/conf'
> --- tribes/empire/goldmine/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/goldmine/conf	2014-10-03 21:34:06 +0000
> @@ -3,9 +3,9 @@
>  enhancement=deep_goldmine
>  
>  [aihints]
> -build_material=false
>  mines=gold
>  mines_percent=50
> +prohibited_till=1200
>  
>  [buildcost]
>  log=4
> 
> === modified file 'tribes/empire/grape/conf'
> --- tribes/empire/grape/conf	2014-07-28 14:04:36 +0000
> +++ tribes/empire/grape/conf	2014-10-03 21:34:06 +0000
> @@ -1,7 +1,7 @@
>  help=_These grapes are the base for a tasty wine. They are harvested in a vineyard and processed in a winery.
>  
>  default_target_quantity=20 # currently not used
> -preciousness=2
> +preciousness=9
>  
>  [idle]
>  pics=grape_idle.png
> 
> === modified file 'tribes/empire/hunters_house/conf'
> --- tribes/empire/hunters_house/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/hunters_house/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,6 @@
>  output=meat
>  
>  [aihints]
> -build_material=false
>  
>  [buildcost]
>  log=1
> 
> === modified file 'tribes/empire/lumberjacks_house/conf'
> --- tribes/empire/lumberjacks_house/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/lumberjacks_house/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=log
>  
>  [aihints]
> -is_basic=true
> +forced_after=0
>  logproducer=true
>  
>  [buildcost]
> 
> === modified file 'tribes/empire/marblemine/conf'
> --- tribes/empire/marblemine/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/marblemine/conf	2014-10-03 21:34:06 +0000
> @@ -6,7 +6,7 @@
>  [aihints]
>  mines=granite
>  mines_percent=50
> -marbleproducer=true
> +prohibited_till=450
>  
>  [buildcost]
>  log=4
> 
> === modified file 'tribes/empire/mill/conf'
> --- tribes/empire/mill/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/mill/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=flour
>  
>  [aihints]
> -build_material=false
> +prohibited_till=600
>  
>  [buildcost]
>  log=3
> 
> === modified file 'tribes/empire/oremine/conf'
> --- tribes/empire/oremine/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/oremine/conf	2014-10-03 21:34:06 +0000
> @@ -3,9 +3,9 @@
>  enhancement=deep_oremine
>  
>  [aihints]
> -build_material=false
>  mines=iron
>  mines_percent=50
> +prohibited_till=1200
>  
>  [buildcost]
>  log=4
> 
> === modified file 'tribes/empire/outpost/conf'
> --- tribes/empire/outpost/conf	2014-07-28 12:48:04 +0000
> +++ tribes/empire/outpost/conf	2014-10-03 21:34:06 +0000
> @@ -12,6 +12,7 @@
>  
>  [aihints]
>  expansion=true
> +prohibited_till=600
>  
>  [buildcost]
>  log=1
> 
> === modified file 'tribes/empire/piggery/conf'
> --- tribes/empire/piggery/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/piggery/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,6 @@
>  output=meat
>  
>  [aihints]
> -build_material=false
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/empire/quarry/conf'
> --- tribes/empire/quarry/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/quarry/conf	2014-10-03 21:34:06 +0000
> @@ -3,7 +3,7 @@
>  output=marble
>  
>  [aihints]
> -is_basic=true
> +forced_after=0
>  stoneproducer=true
>  
>  [buildcost]
> 
> === modified file 'tribes/empire/sawmill/conf'
> --- tribes/empire/sawmill/conf	2014-07-27 19:32:24 +0000
> +++ tribes/empire/sawmill/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,8 @@
>  output=wood
>  
>  [aihints]
> -is_basic=true
> +forced_after=60
> +prohibited_till=60
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/empire/scouts_house/conf'
> --- tribes/empire/scouts_house/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/scouts_house/conf	2014-10-03 21:34:06 +0000
> @@ -1,7 +1,6 @@
>  size=small
>  
>  [aihints]
> -build_material=false
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/empire/sheepfarm/conf'
> --- tribes/empire/sheepfarm/conf	2014-07-27 19:32:24 +0000
> +++ tribes/empire/sheepfarm/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,7 @@
>  output=wool
>  
>  [aihints]
> -build_material=false
> +prohibited_till=600
>  
>  [buildcost]
>  log=2
> @@ -39,3 +39,4 @@
>  [working]
>  pics=sheepfarm_i_??.png  # ???
>  hotspot=73 60
> +
> 
> === modified file 'tribes/empire/shipyard/conf'
> --- tribes/empire/shipyard/conf	2014-09-30 08:05:35 +0000
> +++ tribes/empire/shipyard/conf	2014-10-03 21:34:06 +0000
> @@ -1,7 +1,6 @@
>  size=medium
>  
>  [aihints]
> -build_material=false
>  needs_water=true
>  
>  [buildcost]
> 
> === modified file 'tribes/empire/smelting_works/conf'
> --- tribes/empire/smelting_works/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/smelting_works/conf	2014-10-03 21:34:06 +0000
> @@ -3,7 +3,7 @@
>  output=gold
>  
>  [aihints]
> -build_material=false
> +prohibited_till=600
>  
>  [buildcost]
>  log=1
> 
> === modified file 'tribes/empire/stonemasons_house/conf'
> --- tribes/empire/stonemasons_house/conf	2014-07-27 19:32:24 +0000
> +++ tribes/empire/stonemasons_house/conf	2014-10-03 21:34:06 +0000
> @@ -2,7 +2,8 @@
>  output=marblecolumn
>  
>  [aihints]
> -is_basic=true
> +forced_after=300
> +prohibited_till=120
>  
>  [buildcost]
>  log=1
> 
> === modified file 'tribes/empire/tavern/conf'
> --- tribes/empire/tavern/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/tavern/conf	2014-10-03 21:34:06 +0000
> @@ -3,8 +3,8 @@
>  enhancement=inn
>  
>  [aihints]
> -build_material=false
> -is_food_basic=true
> +forced_after=900
> +prohibited_till=300
>  
>  [buildcost]
>  wood=2
> 
> === modified file 'tribes/empire/toolsmithy/conf'
> --- tribes/empire/toolsmithy/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/toolsmithy/conf	2014-10-03 21:34:06 +0000
> @@ -13,8 +13,8 @@
>  output=saw
>  
>  [aihints]
> -build_material=false
> -is_basic=true
> +forced_after=1200
> +prohibited_till=120
>  
>  [buildcost]
>  log=1
> 
> === modified file 'tribes/empire/tower/conf'
> --- tribes/empire/tower/conf	2014-07-28 12:48:04 +0000
> +++ tribes/empire/tower/conf	2014-10-03 21:34:06 +0000
> @@ -12,6 +12,7 @@
>  
>  [aihints]
>  mountain_conqueror=true
> +prohibited_till=300
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/empire/trainingcamp/conf'
> --- tribes/empire/trainingcamp/conf	2014-07-27 19:32:24 +0000
> +++ tribes/empire/trainingcamp/conf	2014-10-03 21:34:06 +0000
> @@ -125,3 +125,6 @@
>  [idle]
>  pics=trainingcamp_i_??.png  # ???
>  hotspot=82 105
> +
> +[aihints]
> +prohibited_till=2700
> 
> === modified file 'tribes/empire/vineyard/conf'
> --- tribes/empire/vineyard/conf	2014-07-27 19:32:24 +0000
> +++ tribes/empire/vineyard/conf	2014-10-03 21:34:06 +0000
> @@ -3,9 +3,7 @@
>  
>  [aihints]
>  space_consumer=true
> -is_basic=true
> -build_material=false
> -is_food_basic=true
> +forced_after=120
>  
>  [buildcost]
>  wood=2
> 
> === modified file 'tribes/empire/weaponsmithy/conf'
> --- tribes/empire/weaponsmithy/conf	2014-07-27 19:32:24 +0000
> +++ tribes/empire/weaponsmithy/conf	2014-10-03 21:34:06 +0000
> @@ -6,7 +6,7 @@
>  output=war_lance
>  
>  [aihints]
> -build_material=false
> +prohibited_till=900
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/empire/weaving-mill/conf'
> --- tribes/empire/weaving-mill/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/weaving-mill/conf	2014-10-03 21:34:06 +0000
> @@ -43,3 +43,6 @@
>  pics=weaving_mill_w_??.png  # ???
>  hotspot=65 62
>  fps=5
> +
> +[aihints]
> +prohibited_till=120
> 
> === modified file 'tribes/empire/well/conf'
> --- tribes/empire/well/conf	2014-07-29 09:27:08 +0000
> +++ tribes/empire/well/conf	2014-10-03 21:34:06 +0000
> @@ -2,8 +2,8 @@
>  output=water
>  
>  [aihints]
> -build_material=false
>  mines_water=true
> +prohibited_till=60
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/empire/wine/conf'
> --- tribes/empire/wine/conf	2014-07-28 14:04:36 +0000
> +++ tribes/empire/wine/conf	2014-10-03 21:34:06 +0000
> @@ -1,7 +1,7 @@
>  help=_This tasty wine is drunk by the miners working the marble and gold mines. It is produced in a winery. 
>  
>  default_target_quantity=20 # currently not used
> -preciousness=2
> +preciousness=8
>  
>  [idle]
>  pics=idle.png
> 
> === modified file 'tribes/empire/winery/conf'
> --- tribes/empire/winery/conf	2014-07-27 19:32:24 +0000
> +++ tribes/empire/winery/conf	2014-10-03 21:34:06 +0000
> @@ -2,8 +2,8 @@
>  output=wine
>  
>  [aihints]
> -build_material=false
> -is_food_basic=true
> +forced_after=900
> +prohibited_till=60
>  
>  [buildcost]
>  wood=1
> 


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


References