Review: Needs Fixing

Please change the AI hint from ts_type=2 to something that is more 
understandable outside of the AI context, maybe 
trainingssite_type="no_bread_just_meat" or something along these lines. Numbers 
are fully opaque to everybody that looks at the conf files. 

Diff comments:

> === modified file 'src/ai/ai_help_structs.h'
> --- src/ai/ai_help_structs.h  2015-03-05 20:57:07 +0000
> +++ src/ai/ai_help_structs.h  2015-03-23 21:37:01 +0000
> @@ -40,7 +40,7 @@
>  class ProductionSite;
>  class MilitarySite;
>  
> -enum class ExtendedBool : uint8_t {kUnset, kTrue, kFalse };
> +enum class ExtendedBool : uint8_t {kUnset, kTrue, kFalse};
>  
>  struct CheckStepRoadAI {
>       CheckStepRoadAI(Player* const pl, uint8_t const mc, bool const oe)
> @@ -110,6 +110,22 @@
>       }
>  };
>  
> +// Sometimes we need to know how many nodes our allies owns
> +struct FindNodeAllyOwned {
> +     bool accept(const Map&, const FCoords& fc) const {
> +             return (fc.field->nodecaps() & MOVECAPS_WALK) && 
> (fc.field->get_owned_by() != 0) &&
> +                    (fc.field->get_owned_by() != pn) &&
> +                    
> !player_->is_hostile(*game.get_player(fc.field->get_owned_by()));
> +     }
> +
> +     Player* player_;
> +     Game& game;
> +     PlayerNumber pn;
> +
> +     FindNodeAllyOwned(Player* p, Game& g, PlayerNumber n) : player_(p), 
> game(g), pn(n) {
> +     }
> +};
> +
>  // When looking for unowned terrain to acquire, we must
>  // pay speciall attention to fields where mines can be built.
>  // Fields should be completely unowned
> @@ -148,8 +164,9 @@
>  
>       bool accept(const Map& /* map */, const FCoords& coord) const {
>               return (world_.terrain_descr(coord.field->terrain_d()).get_is() 
> &
> -                               TerrainDescription::Type::kWater) ||
> -                              
> (world_.terrain_descr(coord.field->terrain_r()).get_is() & 
> TerrainDescription::Type::kWater);
> +                     TerrainDescription::Type::kWater) ||
> +                    (world_.terrain_descr(coord.field->terrain_r()).get_is() 
> &
> +                     TerrainDescription::Type::kWater);
>       }
>  
>  private:
> @@ -213,7 +230,7 @@
>  struct BuildableField {
>       Widelands::FCoords coords;
>  
> -     uint32_t next_update_due_;
> +     uint32_t field_info_expiration_;
>  
>       bool preferred_;
>       bool enemy_nearby_;
> @@ -232,7 +249,7 @@
>       uint8_t space_consumers_nearby_;
>       // to manage the military better following variables exists:
>       // capacity of nearby buildings:
> -     int16_t military_capacity_;
> +     int16_t area_military_capacity_;
>       // distance to near buldings:
>       int16_t military_loneliness_;
>       // count of military buildings in construction
> @@ -241,7 +258,7 @@
>       // are construction sites that will change this once they are built
>       int16_t military_in_constr_nearby_;
>       // actual count of soldiers in nearby buldings
> -     int16_t military_presence_;
> +     int16_t area_military_presence_;
>       // stationed (manned) military buildings nearby
>       int16_t military_stationed_;
>       // stationed (manned) military buildings nearby
> @@ -256,7 +273,7 @@
>  
>       BuildableField(const Widelands::FCoords& fc)
>          : coords(fc),
> -          next_update_due_(0),
> +          field_info_expiration_(20000),
>            preferred_(false),
>            enemy_nearby_(0),
>            unowned_land_nearby_(0),
> @@ -277,10 +294,10 @@
>            critters_nearby_(-1),
>            ground_water_(1),
>            space_consumers_nearby_(0),
> -          military_capacity_(0),
> +          area_military_capacity_(0),
>            military_loneliness_(1000),
>            military_in_constr_nearby_(0),
> -          military_presence_(0),
> +          area_military_presence_(0),
>            military_stationed_(0),
>            military_unstationed_(0),
>            is_portspace_(false),
> @@ -292,7 +309,7 @@
>  struct MineableField {
>       Widelands::FCoords coords;
>  
> -     uint32_t next_update_due_;
> +     uint32_t field_info_expiration_;
>  
>       bool preferred_;
>  
> @@ -302,7 +319,7 @@
>  
>       MineableField(const Widelands::FCoords& fc)
>          : coords(fc),
> -          next_update_due_(0),
> +          field_info_expiration_(20000),
>            preferred_(false),
>            mines_nearby_(0),
>            same_mine_fields_nearby_(0) {
> @@ -346,14 +363,16 @@
>       bool is_fisher_;    // need to identify fishers
>       bool is_port_;
>       bool is_shipyard_;
> -     bool space_consumer_;      // farm, vineyard... = true
> -     bool expansion_type_;      // military building used that can be used 
> to control area
> -     bool fighting_type_;       // military building built near enemies
> -     bool mountain_conqueror_;  // military building built near mountains
> +     bool 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
>       uint32_t prohibited_till_;  // do not build before (ms)
>       uint32_t forced_after_;     // do not wait until ware is needed
> +     uint8_t ts_type_;
>  
> -     bool unoccupied_;  //
> +     bool unoccupied_;
> +     uint16_t unconnected_;  // to any warehouse (count of such buildings)
>  
>       int32_t mines_;           // type of resource it mines_
>       uint16_t mines_percent_;  // % of res it can mine
> @@ -429,4 +448,44 @@
>       uint8_t preciousness_;
>  };
>  
> +//Computer player does not get notification messages about enemy 
> militarysites
> +//and warehouses, so following is collected based on observation
> +//It is conventient to have some information preserved, like nearby 
> minefields,
> +//when it was attacked, whether it is warehouse and so on
> +//Also AI test more such targets when considering attack and calculated 
> score is
> +//is stored in the observer
> +struct EnemySiteObserver {
> +     bool warehouse_;
> +     uint8_t attack_soldiers;
> +     uint8_t defenders;
> +     uint8_t stationed_soldiers;
> +     uint32_t last_time_attackable;
> +     uint32_t last_tested;
> +     int16_t score;
> +     bool warehouse;
> +     Widelands::ExtendedBool mines_nearby;
> +     int16_t no_attack_counter;
> +
> +     EnemySiteObserver()
> +        : warehouse_(false),
> +          attack_soldiers(0),
> +          stationed_soldiers(0),
> +          last_time_attackable(std::numeric_limits<uint32_t>::max()),
> +          last_tested(0),
> +          score(0),
> +          mines_nearby(Widelands::ExtendedBool::kUnset),
> +          no_attack_counter(0) {
> +     }
> +};
> +
> +// as all mines have 3 levels, AI does not know total count of mines per 
> mined material
> +// so this observer will be used for this
> +struct MineTypesObserver {
> +     uint16_t in_construction;
> +     uint16_t finished;
> +
> +     MineTypesObserver() : in_construction(0), finished(0) {
> +     }
> +};
> +
>  #endif  // end of include guard: WL_AI_AI_HELP_STRUCTS_H
> 
> === modified file 'src/ai/ai_hints.cc'
> --- src/ai/ai_hints.cc        2015-03-05 20:57:07 +0000
> +++ src/ai/ai_hints.cc        2015-03-23 21:37:01 +0000
> @@ -33,7 +33,8 @@
>       mountain_conqueror_(section ? section->get_bool("mountain_conqueror") : 
> false),
>       prohibited_till_(section ? section->get_natural("prohibited_till", 0) : 
> 0),
>       forced_after_(section ? section->get_natural("forced_after", 864000) : 
> 0),  // 10 days default
> -     mines_percent_(section ? section->get_int("mines_percent", 100) : 0)
> +     mines_percent_(section ? section->get_int("mines_percent", 100) : 0),
> +     ts_type_(section ? section->get_int("ts_type", 0) : 0)
>  {
>       if (section) {
>               if (section->has_val("renews_map_resource"))
> 
> === modified file 'src/ai/ai_hints.h'
> --- src/ai/ai_hints.h 2015-03-05 20:57:07 +0000
> +++ src/ai/ai_hints.h 2015-03-23 21:37:01 +0000
> @@ -94,6 +94,10 @@
>               return mines_percent_;
>       }
>  
> +     uint8_t get_ts_type() const {
> +             return ts_type_;
> +     }
> +
>  private:
>       std::string renews_map_resource_;
>       std::string mines_;
> @@ -109,6 +113,7 @@
>       int32_t prohibited_till_;
>       int32_t forced_after_;
>       uint8_t mines_percent_;
> +     uint8_t ts_type_;
>  
>       DISALLOW_COPY_AND_ASSIGN(BuildingHints);
>  };
> 
> === modified file 'src/ai/defaultai.cc'
> --- src/ai/defaultai.cc       2015-03-06 07:36:40 +0000
> +++ src/ai/defaultai.cc       2015-03-23 21:37:01 +0000
> @@ -51,12 +51,15 @@
>  #include "profile/profile.h"
>  
>  // following is in miliseconds (widelands counts time in ms)
> -constexpr int kFieldUpdateInterval = 2000;
> -constexpr int kIdleMineUpdateInterval = 22000;
> +// constexpr int kFieldUpdateInterval = 2000;
> +constexpr int kFieldInfoExpiration = 12 * 1000;
> +constexpr int kMineFieldInfoExpiration = 20 * 1000;
> +constexpr int kNewMineConstInterval = 19000;
>  constexpr int kBusyMineUpdateInterval = 2000;
>  // building of the same building can be started after 25s at earliest
>  constexpr int kBuildingMinInterval = 25 * 1000;
>  constexpr int kMinBFCheckInterval = 5 * 1000;
> +constexpr int kMinMFCheckInterval = 19 * 1000;
>  constexpr int kShipCheckInterval = 5 * 1000;
>  constexpr int kMarineDecisionInterval = 20 * 1000;
>  constexpr int kTrainingSitesCheckInterval = 5 * 60 * 1000;
> @@ -85,6 +88,8 @@
>       num_milit_constructionsites(0),
>       num_prod_constructionsites(0),
>       num_ports(0),
> +     last_attacked_player_(std::numeric_limits<uint16_t>::max()),
> +     enemysites_check_delay_(60),
>       next_ai_think_(0),
>       next_mine_construction_due_(0),
>       inhibit_road_building_(0),
> @@ -92,9 +97,8 @@
>       enemy_last_seen_(0),
>       numof_warehouses_(0),
>       new_buildings_stop_(false),
> -     resource_necessity_territory_(255),
> -     resource_necessity_mines_(255),
> -     resource_necessity_stones_(255),
> +     resource_necessity_territory_(100),
> +     resource_necessity_mines_(100),
>       resource_necessity_water_(0),
>       resource_necessity_water_needed_(false),
>       unstationed_milit_buildings_(0),
> @@ -105,7 +109,13 @@
>       next_attack_waittime_(10),
>       seafaring_economy(false),
>       colony_scan_area_(35),
> -     spots_(0) {
> +     spots_(0),
> +     vacant_mil_positions_(0),
> +     ts_type1_count_(0),
> +     ts_type1_const_count_(0),
> +     ts_type2_count_(0),
> +     ts_type2_const_count_(0),
> +     ts_without_trainers_(0) {
>  
>       // Subscribe to NoteFieldPossession.
>       field_possession_subscriber_ =
> @@ -166,23 +176,23 @@
>                          break;
>  
>                       case NoteShipMessage::Message::kLost:
> -                        for (std::list<ShipObserver>::iterator i = 
> allships.begin(); i != allships.end(); ++i) {
> +                             for (std::list<ShipObserver>::iterator i = 
> allships.begin(); i != allships.end(); ++i) {
>                                       if (i->ship == note.ship) {
>                                          allships.erase(i);
>                                          break;
>                                  }
>                          }
> -                        break;
> +                             break;
>  
>                       case NoteShipMessage::Message::kWaitingForCommand:
> -                        for (std::list<ShipObserver>::iterator i = 
> allships.begin(); i != allships.end(); ++i) {
> +                             for (std::list<ShipObserver>::iterator i = 
> allships.begin(); i != allships.end(); ++i) {
>                                       if (i->ship == note.ship) {
>                                          i->waiting_for_command_ = true;
>                                          break;
>                                  }
>                          }
> -                        break;
> -                default:
> +                             break;
> +                     default:
>                               ;
>                  }
>               });
> @@ -236,7 +246,11 @@
>       if (DueTask == ScheduleTasks::kBbuildableFieldsCheck) {

replacing these if /elif clases through one switch() will make them more 
efficient and easier to read.

>               update_all_buildable_fields(gametime);
>               taskDue[ScheduleTasks::kBbuildableFieldsCheck] = gametime + 
> kMinBFCheckInterval;
> -     } else if (DueTask == ScheduleTasks::kRoadCheck) {
> +     } else if (DueTask == ScheduleTasks::kMineableFieldsCheck) {
> +             update_all_mineable_fields(gametime);
> +             taskDue[ScheduleTasks::kMineableFieldsCheck] = gametime + 
> kMinMFCheckInterval;
> +     }
> +     if (DueTask == ScheduleTasks::kRoadCheck) {
>               if (check_economies()) {  // is a must
>                       return;
>               };
> @@ -245,8 +259,6 @@
>       } else if (DueTask == ScheduleTasks::kUnbuildableFCheck) {
>               taskDue[ScheduleTasks::kUnbuildableFCheck] = gametime + 4000;
>               update_all_not_buildable_fields();
> -     } else if (DueTask == ScheduleTasks::kConsiderAttack) {
> -             consider_attack(gametime);
>       } else if (DueTask == ScheduleTasks::kCheckEconomies) {
>               check_economies();
>               taskDue[ScheduleTasks::kCheckEconomies] = gametime + 8000;
> @@ -280,6 +292,9 @@
>               check_militarysites(gametime);
>       } else if (DueTask == ScheduleTasks::kCheckTrainingsites) {
>               check_trainingsites(gametime);
> +     } else if (DueTask == ScheduleTasks::kCountMilitaryVacant) {
> +             count_military_vacant_positions();
> +             taskDue[ScheduleTasks::kCountMilitaryVacant] = gametime + 90 * 
> 1000;
>       } else if (DueTask == ScheduleTasks::kWareReview) {
>               if (check_economies()) {  // economies must be consistent
>                       return;
> @@ -291,6 +306,9 @@
>                       return;
>               }
>               print_stats(gametime);
> +     } else if (DueTask == ScheduleTasks::kCheckEnemySites) {
> +             check_enemy_sites(gametime);
> +             taskDue[ScheduleTasks::kCheckEnemySites] = gametime + 19 * 1000;
>       }
>  }
>  
> @@ -340,6 +358,7 @@
>               bo.production_hint_ = -1;
>               bo.current_stats_ = 0;
>               bo.unoccupied_ = false;
> +             bo.unconnected_ = 0;
>               bo.is_buildable_ = bld.is_buildable();
>               bo.need_trees_ = bh.is_logproducer();
>               bo.need_stones_ = bh.is_stoneproducer();
> @@ -353,6 +372,8 @@
>               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
>               bo.is_port_ = bld.get_isport();
> +             bo.ts_type_ = bh.get_ts_type();
> +
>               if (bh.renews_map_resource()) {
>                       bo.production_hint_ = 
> tribe_->safe_ware_index(bh.get_renews_map_resource());
>               }
> @@ -382,6 +403,11 @@
>                               }
>  
>                               bo.mines_percent_ = bh.get_mines_percent();
> +
> +                             // populating mines_per_type map
> +                             if (mines_per_type.count(bo.mines_) == 0) {
> +                                     mines_per_type[bo.mines_] = 
> MineTypesObserver();
> +                             }
>                       }
>  
>                       // here we identify hunters
> @@ -439,6 +465,7 @@
>                       for (const WareAmount& temp_input : train.inputs()) {
>                               bo.inputs_.push_back(temp_input.first);
>                       }
> +                     bo.ts_type_ = bh.get_ts_type();
>                       continue;
>               }
>  
> @@ -544,12 +571,14 @@
>       taskDue[ScheduleTasks::kCheckShips] = 30 * 1000;
>       taskDue[ScheduleTasks::kCheckEconomies] = 1000;
>       taskDue[ScheduleTasks::KMarineDecisions] = 30 * 1000;
> -     taskDue[ScheduleTasks::kConsiderAttack] = 300000;
>       taskDue[ScheduleTasks::kCheckTrainingsites] = 15 * 60 * 1000;
>       taskDue[ScheduleTasks::kBbuildableFieldsCheck] = 1000;
> +     taskDue[ScheduleTasks::kMineableFieldsCheck] = 1000;
>       taskDue[ScheduleTasks::kUnbuildableFCheck] = 1000;
>       taskDue[ScheduleTasks::kWareReview] = 15 * 60 * 1000;
>       taskDue[ScheduleTasks::kPrintStats] = 30 * 60 * 1000;
> +     taskDue[ScheduleTasks::kCountMilitaryVacant] = 10 * 60 * 1000;
> +     taskDue[ScheduleTasks::kCheckEnemySites] = 10 * 60 * 1000;
>  }
>  
>  /**
> @@ -562,7 +591,10 @@
>  
>       uint16_t i = 0;
>  
> -     while (!buildable_fields.empty() && 
> buildable_fields.front()->next_update_due_ <= gametime &&
> +     // we test 40 fields that were update more than 1 seconds ago
> +     while (!buildable_fields.empty() &&
> +            (buildable_fields.front()->field_info_expiration_ - 
> kFieldInfoExpiration + 1000) <=
> +               gametime &&
>              i < 40) {
>               BuildableField& bf = *buildable_fields.front();
>  
> @@ -582,7 +614,7 @@
>               }
>  
>               update_buildable_field(bf);
> -             bf.next_update_due_ = gametime + kFieldUpdateInterval;
> +             bf.field_info_expiration_ = gametime + kFieldInfoExpiration;
>               buildable_fields.push_back(&bf);
>               buildable_fields.pop_front();
>  
> @@ -600,8 +632,12 @@
>  
>       uint16_t i = 0;  // counter, used to track # of checked fields
>  
> -     while (!mineable_fields.empty() && 
> mineable_fields.front()->next_update_due_ <= gametime &&
> -            i < 40) {
> +     // we test 30 fields that were updated more than 1 seconds ago
> +     // to avoid re-test of the same field twice
> +     while (!mineable_fields.empty() &&
> +            (mineable_fields.front()->field_info_expiration_ - 
> kMineFieldInfoExpiration + 1000) <=
> +               gametime &&
> +            i < 30) {
>               MineableField* mf = mineable_fields.front();
>  
>               //  check whether we lost ownership of the node
> @@ -620,7 +656,7 @@
>               }
>  
>               update_mineable_field(*mf);
> -             mf->next_update_due_ = gametime + kFieldUpdateInterval;  // in 
> fact this has very small effect
> +             mf->field_info_expiration_ = gametime + 
> kMineFieldInfoExpiration;
>               mineable_fields.push_back(mf);
>               mineable_fields.pop_front();
>  
> @@ -672,32 +708,38 @@
>  void DefaultAI::update_buildable_field(BuildableField& field, uint16_t 
> range, bool military) {
>       // look if there is any unowned land nearby
>       Map& map = game().map();
> +     const int32_t gametime = game().get_gametime();
>       FindNodeUnowned find_unowned(player_, game());
>       FindNodeUnownedMineable find_unowned_mines_pots(player_, game());
>       PlayerNumber const pn = player_->player_number();
>       const World& world = game().world();
>       field.unowned_land_nearby_ =
>          map.find_fields(Area<FCoords>(field.coords, range), nullptr, 
> find_unowned);
> +     FindNodeAllyOwned find_ally(player_, game(), player_number());
> +     const int32_t AllyOwnedFields =
> +        map.find_fields(Area<FCoords>(field.coords, 3), nullptr, find_ally);
>  
>       field.near_border_ = false;
> -     if (field.unowned_land_nearby_ > 0) {
> +     if (AllyOwnedFields > 0) {
> +             field.near_border_ = true;
> +     } else if (field.unowned_land_nearby_ > 0) {
>               if (map.find_fields(Area<FCoords>(field.coords, 4), nullptr, 
> find_unowned) > 0) {
>                       field.near_border_ = true;
>               }
>       }
>  
>       // to save some CPU
> -     if ((mines_.size() > 8 && game().get_gametime() % 3 > 0) || 
> field.unowned_land_nearby_ == 0) {
> +     if ((mines_.size() > 8 && gametime % 3 > 0) || 
> field.unowned_land_nearby_ == 0) {
>               field.unowned_mines_pots_nearby_ = 0;
>       } 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 < 12) 
> ? 12 : range + 6),
> +                map.find_fields(Area<FCoords>(field.coords, (range + 6 < 14) 
> ? 14 : range + 6),
>                                  nullptr,
>                                  find_unowned_mines_pots);
>               distant_mines = distant_mines - close_mines;
> -             field.unowned_mines_pots_nearby_ = 3 * close_mines + 
> distant_mines / 2;
> +             field.unowned_mines_pots_nearby_ = 4 * close_mines + 
> distant_mines / 2;
>               if (distant_mines > 0) {
>                       field.unowned_mines_pots_nearby_ += 15;
>               }
> @@ -710,7 +752,7 @@
>               }
>       }
>  
> -     // testing for near porspaces
> +     // testing for near portspaces
>       if (field.portspace_nearby_ == Widelands::ExtendedBool::kUnset) {
>               field.portspace_nearby_ = ExtendedBool::kFalse;
>               MapRegion<Area<FCoords>> mr(map, Area<FCoords>(field.coords, 
> 2));
> @@ -745,9 +787,9 @@
>               int32_t const tree_attr = 
> MapObjectDescr::get_attribute_id("tree");
>               field.preferred_ = false;
>               field.enemy_nearby_ = false;
> -             field.military_capacity_ = 0;
> +             field.area_military_capacity_ = 0;
>               field.military_loneliness_ = 1000;  // instead of floats(v-
> -             field.military_presence_ = 0;
> +             field.area_military_presence_ = 0;
>               field.military_stationed_ = 0;
>               field.trees_nearby_ = 0;
>               field.space_consumers_nearby_ = 0;
> @@ -772,8 +814,7 @@
>               }
>  
>               // counting fields with fish
> -             if (field.water_nearby_ > 0 &&
> -                 (field.fish_nearby_ == -1 || game().get_gametime() % 10 == 
> 0)) {
> +             if (field.water_nearby_ > 0 && (field.fish_nearby_ == -1 || 
> gametime % 10 == 0)) {
>                       map.find_fields(Area<FCoords>(field.coords, 6),
>                                       &resource_list,
>                                       
> FindNodeResource(world.get_resource("fish")));
> @@ -782,7 +823,7 @@
>  
>               // counting fields with critters (game)
>               // not doing this always, this does not change fast
> -             if (game().get_gametime() % 10 == 0) {
> +             if (gametime % 10 == 0) {
>                       map.find_bobs(Area<FCoords>(field.coords, 6), 
> &critters_list, FindBobCritter());
>                       field.critters_nearby_ = critters_list.size();
>               }
> @@ -808,7 +849,7 @@
>                                       if 
> (player_->is_hostile(player_immovable->owner())) {
>                                               field.enemy_nearby_ = true;
>                                       }
> -                                     enemy_last_seen_ = 
> game().get_gametime();
> +                                     enemy_last_seen_ = gametime;
>  
>                                       continue;
>                               }
> @@ -840,7 +881,7 @@
>               }
>  
>               // stones are not renewable, we will count them only if 
> previous state si nonzero
> -             if (field.stones_nearby_ > 0) {
> +             if (field.stones_nearby_ > 0 && gametime % 3 == 0) {
>  
>                       int32_t const stone_attr = 
> MapObjectDescr::get_attribute_id("granite");
>                       field.stones_nearby_ = 0;
> @@ -863,13 +904,13 @@
>  
>       // we get immovables with higher radius
>       immovables.clear();
> -     map.find_immovables(Area<FCoords>(field.coords, (range < 10) ? 10 : 
> range), &immovables);
> +     map.find_immovables(Area<FCoords>(field.coords, (range < 11) ? 11 : 
> range), &immovables);
>       field.military_stationed_ = 0;
>       field.military_unstationed_ = 0;
>       field.military_in_constr_nearby_ = 0;
> -     field.military_capacity_ = 0;
> +     field.area_military_capacity_ = 0;
>       field.military_loneliness_ = 1000;
> -     field.military_presence_ = 0;
> +     field.area_military_presence_ = 0;
>  
>       for (uint32_t i = 0; i < immovables.size(); ++i) {
>  
> @@ -890,6 +931,7 @@
>                       }
>               }
>  
> +             // if we are here, immovable is ours
>               if (upcast(Building const, building, &base_immovable)) {
>                       if (upcast(ConstructionSite const, constructionsite, 
> building)) {
>                               const BuildingDescr& target_descr = 
> constructionsite->building();
> @@ -899,7 +941,8 @@
>                                       const int32_t radius = 
> target_ms_d->get_conquers() + 4;
>  
>                                       if (radius > dist) {
> -                                             field.military_capacity_ += 
> target_ms_d->get_max_number_of_soldiers() / 2 + 1;
> +                                             field.area_military_capacity_ +=
> +                                                
> target_ms_d->get_max_number_of_soldiers() / 2 + 1;
>                                               field.military_loneliness_ *= 
> static_cast<double_t>(dist) / radius;
>                                               
> field.military_in_constr_nearby_ += 1;
>                                       }
> @@ -912,8 +955,8 @@
>  
>                               if (radius > dist) {
>  
> -                                     field.military_capacity_ += 
> militarysite->max_soldier_capacity();
> -                                     field.military_presence_ += 
> militarysite->stationed_soldiers().size();
> +                                     field.area_military_capacity_ += 
> militarysite->max_soldier_capacity();
> +                                     field.area_military_presence_ += 
> militarysite->stationed_soldiers().size();
>  
>                                       if 
> (militarysite->stationed_soldiers().empty()) {
>                                               field.military_unstationed_ += 
> 1;
> @@ -935,7 +978,7 @@
>       Map& map = game().map();
>       map.find_immovables(Area<FCoords>(field.coords, 5), &immovables);
>       field.preferred_ = false;
> -     field.mines_nearby_ = 1;
> +     field.mines_nearby_ = 0;
>       FCoords fse;
>       map.get_brn(field.coords, &fse);
>  
> @@ -948,11 +991,20 @@
>  
>       for (const ImmovableFound& temp_immovable : immovables) {
>               if (upcast(Building const, bld, temp_immovable.object)) {
> +                     if (player_number() != bld->owner().player_number()) {
> +                             continue;
> +                     }
>                       if (bld->descr().get_ismine()) {
> -                             ++field.mines_nearby_;
> +                             if 
> (get_building_observer(bld->descr().name().c_str()).mines_ ==
> +                                 field.coords.field->get_resources()) {
> +                                     ++field.mines_nearby_;
> +                             }
>                       } else if (upcast(ConstructionSite const, cs, bld)) {
>                               if (cs->building().get_ismine()) {
> -                                     ++field.mines_nearby_;
> +                                     if 
> (get_building_observer(cs->building().name().c_str()).mines_ ==
> +                                         
> field.coords.field->get_resources()) {
> +                                             ++field.mines_nearby_;
> +                                     }
>                               }
>                       }
>               }
> @@ -976,23 +1028,34 @@
>       for (uint32_t i = 0; i < buildings_.size(); ++i) {
>               buildings_.at(i).current_stats_ = 0;
>               buildings_.at(i).unoccupied_ = false;
> +             buildings_.at(i).unconnected_ = 0;
>       }
>  
>       // Check all available productionsites
>       for (uint32_t i = 0; i < productionsites.size(); ++i) {
>               assert(productionsites.front().bo->cnt_built_ > 0);
> -             // 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;
> +             // is connected
> +             const bool connected_to_wh =
> +                
> !productionsites.front().site->get_economy()->warehouses().empty();
> +
> +             // unconnected buildings are excluded from statistics review
> +             if (connected_to_wh) {
> +                     // 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();
> +             } else {
> +                     productionsites.front().bo->unconnected_ += 1;
>               }
>  
> -             // Check whether this building is completely occupied
> -             productionsites.front().bo->unoccupied_ |= 
> !productionsites.front().site->can_start_working();
> -
>               // Now reorder the buildings
>               productionsites.push_back(productionsites.front());
>               productionsites.pop_front();
> @@ -1000,11 +1063,11 @@
>  
>       if (resource_necessity_water_needed_) {
>               if (fishers_count == 0) {
> -                     resource_necessity_water_ = 255;
> +                     resource_necessity_water_ = 100;
>               } else if (fishers_count == 1) {
> -                     resource_necessity_water_ = 150;
> +                     resource_necessity_water_ = 50;
>               } else {
> -                     resource_necessity_water_ = 18;
> +                     resource_necessity_water_ = 10;
>               }
>       }
>  
> @@ -1012,10 +1075,20 @@
>       // Check all available mines
>       for (uint32_t i = 0; i < mines_.size(); ++i) {
>               assert(mines_.front().bo->cnt_built_ > 0);
> -             // Add statistics value
> -             mines_.front().bo->current_stats_ += 
> mines_.front().site->get_statistics_percent();
> -             // Check whether this building is completely occupied
> -             mines_.front().bo->unoccupied_ |= 
> !mines_.front().site->can_start_working();
> +
> +             const bool connected_to_wh =
> +                
> !productionsites.front().site->get_economy()->warehouses().empty();
> +
> +             // unconnected mines are excluded from statistics review
> +             if (connected_to_wh) {
> +                     // Add statistics value
> +                     mines_.front().bo->current_stats_ += 
> mines_.front().site->get_statistics_percent();
> +                     // Check whether this building is completely occupied
> +                     mines_.front().bo->unoccupied_ |= 
> !mines_.front().site->can_start_working();
> +             } else {
> +                     buildings_.at(i).unconnected_ += 1;
> +             }
> +
>               // Now reorder the buildings
>               mines_.push_back(mines_.front());
>               mines_.pop_front();
> @@ -1023,8 +1096,9 @@
>  
>       // Scale statistics down
>       for (uint32_t i = 0; i < buildings_.size(); ++i) {
> -             if (buildings_.at(i).cnt_built_ > 0) {
> -                     buildings_.at(i).current_stats_ /= 
> buildings_.at(i).cnt_built_;
> +             if ((buildings_.at(i).cnt_built_ - 
> buildings_.at(i).unconnected_) > 0) {
> +                     buildings_.at(i).current_stats_ /=
> +                        (buildings_.at(i).cnt_built_ - 
> buildings_.at(i).unconnected_);
>               }
>       }
>  }
> @@ -1100,54 +1174,48 @@
>  
>       // sometimes there is too many military buildings in construction, so 
> we must
>       // prevent initialization of further buildings start
> -     const uint32_t treshold = militarysites.size() / 40 + 2;
> -
> -     if (unstationed_milit_buildings_ + num_milit_constructionsites > 3 * 
> treshold) {
> +     const int32_t vacant_plus_in_construction_minus_prod =
> +        vacant_mil_positions_ + 2 * num_milit_constructionsites - 
> productionsites.size() / 15;
> +     if (vacant_plus_in_construction_minus_prod > 20) {
>               expansion_mode = MilitaryStrategy::kNoNewMilitary;
> -     } else if (unstationed_milit_buildings_ + num_milit_constructionsites > 
> 2 * treshold) {
> +     } else if (vacant_plus_in_construction_minus_prod > 13) {
>               expansion_mode = MilitaryStrategy::kDefenseOnly;
> -     } else if (unstationed_milit_buildings_ + num_milit_constructionsites 
> >= treshold - 1) {
> +     } else if (vacant_plus_in_construction_minus_prod > 6) {
>               expansion_mode = MilitaryStrategy::kResourcesOrDefense;
> -     } else if (unstationed_milit_buildings_ + num_milit_constructionsites 
> >= 1) {
> -             expansion_mode = MilitaryStrategy::kExpansion;
>       } else {
> -             expansion_mode = MilitaryStrategy::kPushExpansion;
> +             if (unstationed_milit_buildings_ + num_milit_constructionsites 
> >= 1) {
> +                     expansion_mode = MilitaryStrategy::kExpansion;
> +             } else {
> +                     expansion_mode = MilitaryStrategy::kPushExpansion;
> +             }
>       }
>  
>       // we must consider need for mines
>       // set necessity for mines
>       // we use 'virtual mines', because also mine spots can be changed
>       // to mines when AI decides so
> -     const int32_t virtual_mines = mines_.size() + mineable_fields.size() / 
> 15;
> -     if (virtual_mines <= 7) {
> -             resource_necessity_mines_ = std::numeric_limits<uint8_t>::max();
> -     } else if (virtual_mines > 19) {
> -             resource_necessity_mines_ = 50;
> +     const int32_t virtual_mines =
> +        mines_.size() + mineable_fields.size() / 15 - productionsites.size() 
> / 25;
> +     resource_necessity_mines_ = 100 * (15 - virtual_mines) / 15;
> +     resource_necessity_mines_ = (resource_necessity_mines_ > 100) ? 100 : 
> resource_necessity_mines_;
> +     resource_necessity_mines_ = (resource_necessity_mines_ < 20) ? 10 : 
> resource_necessity_mines_;
> +
> +     // here we calculate how badly we need to expand, result is number 
> (0-100)
> +     // like a percent
> +     if (spots_ == 0) {
> +             resource_necessity_territory_ = 100;
>       } else {
> -             const uint32_t tmp = (24 - virtual_mines) * 10;
> -             resource_necessity_mines_ = tmp;
> -     }
> -
> -     // here we calculate a need for expansion and reduce necessity for new 
> land
> -     // the game has two stages:
> -     // First: virtual mines<=5 - stage of building the economics
> -     // Second: virtual mines>5 - teritorial expansion
> -     if (virtual_mines <= 5) {
> -             if (spots_avail.at(BUILDCAPS_BIG) <= 4) {
> -                     resource_necessity_territory_ = 255;
> -             } else {
> -                     resource_necessity_territory_ = 0;
> +             resource_necessity_territory_ = 100 * 5 * 
> (productionsites.size() + 5) / spots_;
> +             resource_necessity_territory_ =
> +                (resource_necessity_territory_ > 100) ? 100 : 
> resource_necessity_territory_;
> +             resource_necessity_territory_ =
> +                (resource_necessity_territory_ < 10) ? 10 : 
> resource_necessity_territory_;
> +             // alse we need at lest 4 big spots
> +             if (spots_avail.at(BUILDCAPS_BIG) < 2) {
> +                     resource_necessity_territory_ = 100;
>               }
> -     } else {  // or we have enough mines and regulate speed of expansion
> -             if (spots_ == 0) {
> -                     resource_necessity_territory_ = 255;
> -             } else {
> -                     const uint32_t tmp = 255 * 4 * productionsites.size() / 
> spots_;
> -                     if (tmp > 255) {
> -                             resource_necessity_territory_ = 255;
> -                     } else {
> -                             resource_necessity_territory_ = tmp;
> -                     }
> +             if (spots_avail.at(BUILDCAPS_MEDIUM) < 4) {
> +                     resource_necessity_territory_ = 100;
>               }
>       }
>  
> @@ -1205,7 +1273,7 @@
>            ++i) {
>               BuildableField* const bf = *i;
>  
> -             if (bf->next_update_due_ < gametime - 10000) {
> +             if (bf->field_info_expiration_ < gametime) {
>                       continue;
>               }
>  
> @@ -1369,7 +1437,7 @@
>                                               continue;
>                                       }
>  
> -                                     if (bo.total_count() == 0) {
> +                                     if (bo.total_count() - bo.unconnected_ 
> == 0) {
>                                               prio += 150;
>                                       }
>  
> @@ -1394,12 +1462,15 @@
>                                               continue;
>                                       }
>  
> -                                     if (new_buildings_stop_) {
> +                                     if (gametime > 5 * 60 * 1000 &&
> +                                     (bo.total_count() - bo.unconnected_  == 
> 0)) {
> +                                             prio += 10;
> +                                     } else if (new_buildings_stop_) {
>                                               continue;
>                                       }
>  
>                                       prio +=
> -                                        (bf->critters_nearby_ * 2) - 8 - 5 * 
> bf->producers_nearby_.at(bo.outputs_.at(0));
> +                                        (bf->critters_nearby_ * 3) - 8 - 5 * 
> bf->producers_nearby_.at(bo.outputs_.at(0));
>  
>                               } else if (bo.is_fisher_) {  // fisher
>  
> @@ -1490,7 +1561,7 @@
>                                               prio -= 
> bf->space_consumers_nearby_ * 5;
>  
>                                       } else {  // FISH BREEDERS and GAME 
> KEEPERS
> -                                             if (new_buildings_stop_ && 
> bo.total_count() > 0) {
> +                                             if (new_buildings_stop_ && 
> (bo.total_count() - bo.unconnected_) > 0) {
>                                                       continue;
>                                               }
>  
> @@ -1502,7 +1573,7 @@
>                                                       prio += 
> bf->water_nearby_ / 5;
>                                               }
>  
> -                                             if (bo.total_count() > 
> bo.cnt_target_) {
> +                                             if ((bo.total_count() - 
> bo.unconnected_) > bo.cnt_target_) {
>                                                       continue;
>                                               }
>  
> @@ -1543,9 +1614,10 @@
>                                               continue;
>                                       }
>  
> -                                     if (bo.forced_after_ < gametime && 
> bo.total_count() == 0) {
> +                                     if (bo.forced_after_ < gametime && 
> (bo.total_count() - bo.unconnected_) == 0) {
>                                               prio += 150;
> -                                     } else if (bo.cnt_built_ == 1 && 
> game().get_gametime() > 40 * 60 * 1000 &&
> +                                     } else if ((bo.cnt_built_ - 
> bo.unconnected_) == 1 &&
> +                                                game().get_gametime() > 40 * 
> 60 * 1000 &&
>                                                  bo.desc->enhancement() != 
> INVALID_INDEX && !mines_.empty()) {
>                                               prio += 10;
>                                       } else if (bo.is_shipyard_) {
> @@ -1554,9 +1626,10 @@
>                                               }
>                                       } else if (!output_is_needed) {
>                                               continue;
> -                                     } else if (bo.cnt_built_ == 0 && 
> game().get_gametime() > 40 * 60 * 1000) {
> +                                     } else if ((bo.cnt_built_ - 
> bo.unconnected_) == 0 &&
> +                                                game().get_gametime() > 40 * 
> 60 * 1000) {
>                                               prio += kDefaultPrioBoost;
> -                                     } else if (bo.cnt_built_ > 1 && 
> bo.current_stats_ > 97) {
> +                                     } else if ((bo.cnt_built_ - 
> bo.unconnected_) > 1 && bo.current_stats_ > 97) {
>                                               prio -= kDefaultPrioBoost * 
> (new_buildings_stop_);
>                                       } else if (new_buildings_stop_)
>                                               continue;
> @@ -1593,15 +1666,16 @@
>  
>                                       else if (bo.is_shipyard_) {
>                                               // for now AI builds only one 
> shipyard
> -                                             if (bf->water_nearby_ > 3 && 
> bo.total_count() == 0 && seafaring_economy) {
> +                                             if (bf->water_nearby_ > 3 && 
> (bo.total_count() - bo.unconnected_) == 0 &&
> +                                                 seafaring_economy) {
>                                                       prio += 
> kDefaultPrioBoost + productionsites.size() * 5 + bf->water_nearby_;
>                                               }
>  
>                                       } else if (!bo.inputs_.empty()) {
> -                                             if (bo.total_count() == 0) {
> +                                             if ((bo.total_count() == 0 - 
> bo.unconnected_)) {
>                                                       prio += 
> max_needed_preciousness + kDefaultPrioBoost;
>                                               }
> -                                             if (bo.cnt_built_ > 0 && 
> bo.current_stats_ > 70) {
> +                                             if ((bo.cnt_built_ - 
> bo.unconnected_) > 0 && bo.current_stats_ > 70) {
>                                                       prio += 
> max_needed_preciousness + kDefaultPrioBoost - 3 +
>                                                               
> (bo.current_stats_ - 70) / 5;
>                                               }
> @@ -1623,7 +1697,6 @@
>                               }
>                       }  // production sites done
>                       else if (bo.type == BuildingObserver::MILITARYSITE) {
> -
>                               // we allow 1 exemption from big buildings 
> prohibition
>                               if (bo.build_material_shortage_ &&
>                                   (bo.cnt_under_construction_ > 0 || 
> !(bf->enemy_nearby_))) {
> @@ -1631,6 +1704,7 @@
>                               }
>  
>                               if (!bf->unowned_land_nearby_) {
> +
>                                       continue;
>                               }
>  
> @@ -1648,8 +1722,7 @@
>  
>                               if (expansion_mode == 
> MilitaryStrategy::kResourcesOrDefense &&
>                                   !(bf->unowned_mines_pots_nearby_ || 
> bf->stones_nearby_ || bf->water_nearby_ ||
> -                                   (bf->distant_water_ && 
> resource_necessity_water_needed_) ||
> -                                   bf->enemy_nearby_)) {
> +                                   (bf->distant_water_ && 
> resource_necessity_water_needed_) || bf->enemy_nearby_)) {
>                                       continue;
>                               }
>  
> @@ -1667,31 +1740,40 @@
>                                       if (bo.desc->get_size() == 3 && 
> gametime % 3 >= 1) {
>                                               continue;
>                                       };
> -                             }
> -                             else {
> +                             } else {
>                                       continue;
>                               }  // the building is not suitable for situation
> -
>                               // not to build so many military buildings 
> nearby
>                               if (!bf->enemy_nearby_ &&
>                                   (bf->military_in_constr_nearby_ + 
> bf->military_unstationed_) > 0) {
>                                       continue;
>                               }
> -
>                               // a boost to prevent an expansion halt
>                               int32_t local_boost = 0;
>                               if (expansion_mode == 
> MilitaryStrategy::kPushExpansion) {
>                                       local_boost = 200;
>                               }
>  
> -                             prio = ((bf->unowned_land_nearby_ * 2 * 
> resource_necessity_territory_) / 255 +
> -                                     (bf->unowned_mines_pots_nearby_ * 
> resource_necessity_mines_) / 255 +
> -                                     bf->stones_nearby_ / 2 + 
> bf->military_loneliness_ / 10 - 60 + local_boost +
> -                                     (bf->water_nearby_ * 
> resource_necessity_water_) / 255);
> +                             // priority based on basic resources
> +                             prio = ((bf->unowned_mines_pots_nearby_ * 
> resource_necessity_mines_) / 100 +
> +                                     bf->stones_nearby_ + 
> bf->military_loneliness_ / 10 - 40 + local_boost +
> +                                     (bf->water_nearby_ * 
> resource_necessity_water_) / 100);
> +
> +                             // Depending on wheter resource only are 
> considered or no
> +                             if (expansion_mode == 
> MilitaryStrategy::kResourcesOrDefense) {
> +                                     prio *= 2;
> +                                     prio += bf->unowned_land_nearby_ * 
> resource_necessity_territory_ / 100 / 2;
> +                             } else {  // addding score for territory
> +                                     prio += (bf->unowned_land_nearby_ * 
> resource_necessity_territory_) / 100 * 3 / 2;
> +                             }
> +
> +                             // adding score for distance to other military 
> sites
> +                             prio += bf->military_loneliness_ / 10 - 40;
>  
>                               // special bonus due to remote water for 
> atlanteans
> -                             if (resource_necessity_water_needed_)
> -                                     prio += (bf->distant_water_ * 
> resource_necessity_water_) / 255;
> +                             if (resource_necessity_water_needed_) {
> +                                     prio += (bf->distant_water_ * 
> resource_necessity_water_) / 100 / 2;
> +                             }
>  
>                               // special bonus if a portspace is close
>                               if (bf->portspace_nearby_ == 
> ExtendedBool::kTrue) {
> @@ -1702,6 +1784,11 @@
>                                       }
>                               }
>  
> +                             //special bonus for bigger buildings in enemy 
> is nearby
> +                             if (bf->enemy_nearby_) {
> +                                     prio += (bo.desc->get_size() - 1) * 15;
> +                             }
> +
>                               if (bo.desc->get_size() < maxsize) {
>                                       prio = prio - 5;
>                               }  // penalty
> @@ -1713,12 +1800,12 @@
>                               // for expansion)
>                               const int16_t bottom_treshold =
>                                  15 - ((virtual_mines <= 4) ? (5 - 
> virtual_mines) * 2 : 0);
> -                             if (bf->enemy_nearby_ && bf->military_capacity_ 
> < bottom_treshold) {
> -                                     prio += 50 + (bottom_treshold - 
> bf->military_capacity_) * 20;
> +                             if (bf->enemy_nearby_ && 
> bf->area_military_capacity_ < bottom_treshold) {
> +                                     prio += 50 + (bottom_treshold - 
> bf->area_military_capacity_) * 20;
>                               }
>  
> -                             if (bf->enemy_nearby_ && bf->military_capacity_ 
> > bottom_treshold + 4) {
> -                                     prio -= (bf->military_capacity_ - 
> (bottom_treshold + 4)) * 5;
> +                             if (bf->enemy_nearby_ && 
> bf->area_military_capacity_ > bottom_treshold + 4) {
> +                                     prio -= (bf->area_military_capacity_ - 
> (bottom_treshold + 4)) * 5;
>                               }
>  
>                       } else if (bo.type == BuildingObserver::WAREHOUSE) {
> @@ -1780,7 +1867,7 @@
>  
>                               // take care about and enemies
>                               if (bf->enemy_nearby_) {
> -                                     prio /= 2;
> +                                     prio /= 4;
>                               }
>  
>                               if (bf->unowned_land_nearby_ && !bo.is_port_) {
> @@ -1789,24 +1876,43 @@
>  
>                       } else if (bo.type == BuildingObserver::TRAININGSITE) {
>  
> -                             if (virtual_mines < 5) {
> -                                     continue;
> -                             }
> -
>                               // exclude spots on border
>                               if (bf->near_border_) {
>                                       continue;
>                               }
>  
> -                             if (virtual_mines < 3) {
> -                                     continue;
> -                             }
> -
> -                             // build after 20 production sites and then 
> after each 50 production site
> -                             if 
> (static_cast<int32_t>((productionsites.size() + 40) / 60) > bo.total_count() 
> &&
> -                                 bo.cnt_under_construction_ == 0) {
> -                                     prio = 4 + kDefaultPrioBoost;
> -                             }
> +                             // it is a bit difficult to get a new 
> trainer.....
> +                             if (ts_without_trainers_) {
> +                                     continue;
> +                             }
> +
> +                             // target is only one for both types
> +                             if ((ts_type1_const_count_ + 
> ts_type2_const_count_) > 0) {
> +                                     continue;
> +                             }
> +
> +                             // we build one training site for 100 
> militarysites
> +                             if (bo.ts_type_ == 1 &&
> +                                 militarysites.size() / 100 < 
> static_cast<int32_t>(ts_type1_count_)) {
> +                                     continue;
> +                             }
> +                             // we build one training site for 100 
> militarysites
> +                             if (bo.ts_type_ == 2 &&
> +                                 militarysites.size() / 100 < 
> static_cast<int32_t>(ts_type2_count_)) {
> +                                     continue;
> +                             }
> +
> +                             // for type1 we need 15 productionsties
> +                             if (bo.ts_type_ == 1 && productionsites.size() 
> < 15) {
> +                                     continue;
> +                             }
> +
> +                             // for type2 we need 4 mines
> +                             if (bo.ts_type_ == 2 && virtual_mines < 4) {
> +                                     continue;
> +                             }
> +
> +                             prio = 4 + kDefaultPrioBoost;
>  
>                               // take care about borders and enemies
>                               if (bf->enemy_nearby_) {
> @@ -1854,8 +1960,9 @@
>       // then try all mines_ - as soon as basic economy is build up.
>       if (gametime > next_mine_construction_due_) {
>  
> -             update_all_mineable_fields(gametime);
> -             next_mine_construction_due_ = gametime + 
> kIdleMineUpdateInterval;
> +             // not done here
> +             // update_all_mineable_fields(gametime);
> +             next_mine_construction_due_ = gametime + kNewMineConstInterval;
>  
>               if (!mineable_fields.empty()) {
>  
> @@ -1885,22 +1992,33 @@
>                               check_ware_necessity(
>                                  bo, &output_is_needed, &max_preciousness, 
> &max_needed_preciousness);
>  
> -                             if (!output_is_needed && bo.total_count() > 0) {
> +                             if (!output_is_needed && (bo.total_count() - 
> bo.unconnected_) > 0) {
>                                       continue;
>                               }
>  
>                               // if current one(s) are performing badly
> -                             if (bo.total_count() >= 1 && bo.current_stats_ 
> < 50) {
> +                             if ((bo.total_count() - bo.unconnected_) >= 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) {
> +                             if ((mines_per_type[bo.mines_].in_construction 
> + mines_per_type[bo.mines_].finished) ==
> +                                 0) {
>                                       nearness_penalty = 0;
>                               } else {
> -                                     nearness_penalty = 10;
> +                                     nearness_penalty = 30;
> +                             }
> +
> +                             // bonus score to prefer if too few mines
> +                             uint32_t bonus_score = 0;
> +                             if ((mines_per_type[bo.mines_].in_construction 
> + mines_per_type[bo.mines_].finished) ==
> +                                 0) {
> +                                     bonus_score = 15;
> +                             } else if 
> ((mines_per_type[bo.mines_].in_construction +
> +                                         mines_per_type[bo.mines_].finished) 
> == 1) {
> +                                     bonus_score = 5;
>                               }
>  
>                               // iterating over fields
> @@ -1908,26 +2026,46 @@
>                                    j != mineable_fields.end();
>                                    ++j) {
>  
> -                                     if ((*j)->coords.field->get_resources() 
> != bo.mines_) {
> -                                             continue;
> -                                     }
> -
> -                                     int32_t prio = 
> (*j)->coords.field->get_resources_amount();
> +                                     MineableField* const mf = *j;
> +
> +                                     if (mf->field_info_expiration_ <= 
> gametime) {
> +                                             continue;
> +                                     }
> +
> +                                     if (mf->coords.field->get_resources() 
> != bo.mines_) {
> +                                             continue;
> +                                     }
> +
> +                                     int32_t prio = 0;
> +                                     MapRegion<Area<FCoords>> mr(map, 
> Area<FCoords>(mf->coords, 2));
> +                                     do {
> +                                             if (bo.mines_ == 
> mr.location().field->get_resources()) {
> +                                                     prio += 
> mr.location().field->get_resources_amount();
> +                                             }
> +                                     } while (mr.advance(map));
> +
> +                                     prio /= 10;
> +
> +                                     // Only build mines_ on locations where 
> some material can be mined
> +                                     if (prio < 1) {
> +                                             continue;
> +                                     }
>  
>                                       // applying nearnes penalty
> -                                     prio = prio - (*j)->mines_nearby_ * 
> nearness_penalty;
> -
> -                                     // Only build mines_ on locations where 
> some material can be mined
> -                                     if (prio < 2) {
> -                                             continue;
> -                                     }
> +                                     prio -= mf->mines_nearby_ * 
> nearness_penalty;
> +
> +                                     // applying bonus score
> +                                     prio += bonus_score;
> +
> +                                     // applying max needed
> +                                     prio += max_needed_preciousness * 3;
>  
>                                       // prefer mines in the middle of mine 
> fields of the
>                                       // same type, so we add a small bonus 
> here
>                                       // depending on count of same mines 
> nearby,
>                                       // though this does not reflects how 
> many resources
>                                       // are (left) in nearby mines
> -                                     prio += (*j)->same_mine_fields_nearby_ 
> / 3;
> +                                     prio += mf->same_mine_fields_nearby_;
>  
>                                       // Continue if field is blocked at the 
> moment
>                                       bool blocked = false;
> @@ -1946,13 +2084,12 @@
>                                       }
>  
>                                       // Prefer road side fields
> -                                     prio += (*j)->preferred_ ? 1 : 0;
> +                                     prio += mf->preferred_ ? 1 : 0;
>  
>                                       if (prio > proposed_priority) {
> -                                             // proposed_building = bo.id;
>                                               best_building = &bo;
>                                               proposed_priority = prio;
> -                                             proposed_coords = (*j)->coords;
> +                                             proposed_coords = mf->coords;
>                                               mine = true;
>                                       }
>                               }  // end of evaluation of field
> @@ -2257,11 +2394,11 @@
>  
>                               if (occupied_military_) {
>                                       eco->dismantle_grace_time_ =
> -                                        (gametime + 20 * 60 * 1000) + 
> (eco->flags.size() * 20 * 1000);
> +                                        (gametime + 90 * 60 * 1000) + 
> (eco->flags.size() * 20 * 1000);
>  
>                               } else {  // for other normal buildings
>                                       eco->dismantle_grace_time_ =
> -                                        gametime + (5 * 60 * 1000) + 
> (eco->flags.size() * 20 * 1000);
> +                                        gametime + (45 * 60 * 1000) + 
> (eco->flags.size() * 20 * 1000);
>                               }
>                       }
>  
> @@ -2547,6 +2684,9 @@
>               site.unoccupied_till_ = game().get_gametime();
>       }
>  
> +     // is it connected to wh at all?
> +     const bool connected_to_wh = 
> !site.site->get_economy()->warehouses().empty();
> +
>       // 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) {
> @@ -2571,7 +2711,8 @@
>       // 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) {
> +     if (connected_to_wh && enhancement != INVALID_INDEX &&
> +         (site.bo->cnt_built_ - site.bo->unoccupied_) > 1) {
>  
>               BuildingIndex enbld = INVALID_INDEX;  // to get rid of this
>  
> @@ -2664,7 +2805,11 @@
>               // so finally we dismantle the lumberjac
>               site.bo->last_dismantle_time_ = game().get_gametime();
>               
> flags_to_be_removed.push_back(site.site->base_flag().get_position());
> -             game().send_player_dismantle(*site.site);
> +             if (connected_to_wh) {
> +                     game().send_player_dismantle(*site.site);
> +             } else {
> +                     game().send_player_bulldoze(*site.site);
> +             }
>  
>               return true;
>       }
> @@ -2675,7 +2820,11 @@
>                   site.site->get_statistics_percent() == 0) {
>                       site.bo->last_dismantle_time_ = gametime;
>                       
> flags_to_be_removed.push_back(site.site->base_flag().get_position());
> -                     game().send_player_dismantle(*site.site);
> +                     if (connected_to_wh) {
> +                             game().send_player_dismantle(*site.site);
> +                     } else {
> +                             game().send_player_bulldoze(*site.site);
> +                     }
>  
>                       return true;
>               }
> @@ -2695,7 +2844,11 @@
>               if (site.bo->stocklevel_ > 250 + productionsites.size() * 5) {  
> // 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);
> +                     if (connected_to_wh) {
> +                             game().send_player_dismantle(*site.site);
> +                     } else {
> +                             game().send_player_bulldoze(*site.site);
> +                     }
>                       return true;
>               }
>  
> @@ -2714,7 +2867,11 @@
>                       // 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);
> +                     if (connected_to_wh) {
> +                             game().send_player_dismantle(*site.site);
> +                     } else {
> +                             game().send_player_bulldoze(*site.site);
> +                     }
>                       return true;
>               }
>  
> @@ -2723,7 +2880,11 @@
>                       // 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());
> -                     game().send_player_dismantle(*site.site);
> +                     if (connected_to_wh) {
> +                             game().send_player_dismantle(*site.site);
> +                     } else {
> +                             game().send_player_bulldoze(*site.site);
> +                     }
>  
>                       return true;
>               }
> @@ -2743,7 +2904,7 @@
>           site.bo->space_consumer_ && !site.bo->plants_trees_) {
>  
>               // if we have more buildings then target
> -             if (site.bo->cnt_built_ > site.bo->cnt_target_) {
> +             if ((site.bo->cnt_built_ - site.bo->unconnected_) > 
> site.bo->cnt_target_) {
>                       if (site.bo->stocklevel_time < game().get_gametime() - 
> 5 * 1000) {
>                               site.bo->stocklevel_ = get_stocklevel(*site.bo);
>                               site.bo->stocklevel_time = 
> game().get_gametime();
> @@ -2753,7 +2914,11 @@
>                           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);
> +                             if (connected_to_wh) {
> +                                     
> game().send_player_dismantle(*site.site);
> +                             } else {
> +                                     game().send_player_bulldoze(*site.site);
> +                             }
>                               return true;
>                       }
>               }
> @@ -2762,7 +2927,11 @@
>               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);
> +                     if (connected_to_wh) {
> +                             game().send_player_dismantle(*site.site);
> +                     } else {
> +                             game().send_player_bulldoze(*site.site);
> +                     }
>                       return true;
>               }
>  
> @@ -2778,7 +2947,11 @@
>  
>               site.bo->last_dismantle_time_ = game().get_gametime();
>               
> flags_to_be_removed.push_back(site.site->base_flag().get_position());
> -             game().send_player_dismantle(*site.site);
> +             if (connected_to_wh) {
> +                     game().send_player_dismantle(*site.site);
> +             } else {
> +                     game().send_player_bulldoze(*site.site);
> +             }
>               return true;
>       }
>  
> @@ -2792,7 +2965,11 @@
>  
>               site.bo->last_dismantle_time_ = game().get_gametime();
>               
> flags_to_be_removed.push_back(site.site->base_flag().get_position());
> -             game().send_player_dismantle(*site.site);
> +             if (connected_to_wh) {
> +                     game().send_player_dismantle(*site.site);
> +             } else {
> +                     game().send_player_bulldoze(*site.site);
> +             }
>               return true;
>       }
>  
> @@ -2813,16 +2990,29 @@
>  
>                       site.bo->last_dismantle_time_ = game().get_gametime();
>                       
> flags_to_be_removed.push_back(site.site->base_flag().get_position());
> -                     game().send_player_dismantle(*site.site);
> +                     if (connected_to_wh) {
> +                             game().send_player_dismantle(*site.site);
> +                     } else {
> +                             game().send_player_bulldoze(*site.site);
> +                     }
>                       return true;
>               }
>  
>               if (score > 120 && !site.site->is_stopped()) {
>  
>                       game().send_player_start_stop_building(*site.site);
> +                     return true;
>               }
> +             const uint32_t trees_in_vicinity =
> +                
> map.find_immovables(Area<FCoords>(map.get_fcoords(site.site->get_position()), 
> 5),
> +                                    nullptr,
> +                                    
> FindImmovableAttribute(MapObjectDescr::get_attribute_id("tree")));
>  
> -             if (score < 80 && site.site->is_stopped()) {
> +             if (trees_in_vicinity > 25) {
> +                     if (!site.site->is_stopped()) {
> +                             
> game().send_player_start_stop_building(*site.site);
> +                     }
> +             } else if (score < 80 && site.site->is_stopped()) {
>  
>                       game().send_player_start_stop_building(*site.site);
>               }
> @@ -3043,11 +3233,17 @@
>       // Get link to productionsite that should be checked
>       ProductionSiteObserver& site = mines_.front();
>  
> +     const bool connected_to_wh = 
> !site.site->get_economy()->warehouses().empty();
> +
>       // 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_ + 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);
> +             if (connected_to_wh) {
> +                     game().send_player_dismantle(*site.site);
> +             } else {
> +                     game().send_player_bulldoze(*site.site);
> +             }
>               return true;
>       }
>  
> @@ -3059,7 +3255,11 @@
>       // dismantling when the failed count is too high
>       if (site.no_resources_count > 12) {
>               
> flags_to_be_removed.push_back(site.site->base_flag().get_position());
> -             game().send_player_dismantle(*site.site);
> +             if (connected_to_wh) {
> +                     game().send_player_dismantle(*site.site);
> +             } else {
> +                     game().send_player_bulldoze(*site.site);
> +             }
>               site.bo->construction_decision_time_ = gametime;
>               return true;
>       }
> @@ -3084,6 +3284,11 @@
>               return false;
>       }
>  
> +     if (!connected_to_wh) {
> +             // no enhancement possible
> +             return false;
> +     }
> +
>       bool changed = false;
>       if (player_->is_building_type_allowed(enhancement)) {
>               // first exclude possibility there are enhancements in 
> construction or unoccupied_
> @@ -3212,6 +3417,18 @@
>       return count;
>  }
>  
> +// this just counts free positions in military and training sites
> +void DefaultAI::count_military_vacant_positions() {
> +     // counting vacant positions
> +     vacant_mil_positions_ = 0;
> +     for (TrainingSiteObserver tso : trainingsites) {
> +             vacant_mil_positions_ += tso.site->soldier_capacity() - 
> tso.site->stationed_soldiers().size();
> +     }
> +     for (MilitarySiteObserver mso : militarysites) {
> +             vacant_mil_positions_ += mso.site->soldier_capacity() - 
> mso.site->stationed_soldiers().size();
> +     }
> +}
> +
>  // this function only manipulates with trainingsites' inputs priority
>  // decreases it when too many unoccupied military buildings
>  bool DefaultAI::check_trainingsites(uint32_t gametime) {
> @@ -3221,22 +3438,38 @@
>       if (!trainingsites.empty()) {
>               taskDue[ScheduleTasks::kCheckTrainingsites] = gametime + 
> kTrainingSitesCheckInterval;
>       } else {
> -             taskDue[ScheduleTasks::kCheckTrainingsites] = gametime + 5 * 
> kTrainingSitesCheckInterval;
> -     }
> -
> -     uint8_t new_priority = DEFAULT_PRIORITY;
> -     if (unstationed_milit_buildings_ > 2) {
> -             new_priority = LOW_PRIORITY;
> -     } else {
> -             new_priority = DEFAULT_PRIORITY;
> -     }
> +             taskDue[ScheduleTasks::kCheckTrainingsites] = gametime + 2 * 
> kTrainingSitesCheckInterval;
> +             return false;
> +     }
> +
> +     TrainingSite* ts = trainingsites.front().site;
> +     TrainingSiteObserver& tso = trainingsites.front();
> +
> +     const BuildingIndex enhancement = ts->descr().enhancement();
> +
> +     if (enhancement != INVALID_INDEX && ts_without_trainers_ == 0 && 
> mines_.size() > 3 &&
> +         (ts_type1_const_count_ + ts_type2_const_count_) == 0 && 
> ts_type2_count_ > 0) {
> +
> +             if (player_->is_building_type_allowed(enhancement)) {
> +                     game().send_player_enhance_building(*tso.site, 
> enhancement);
> +             }
> +     }
> +
> +     trainingsites.push_back(trainingsites.front());
> +     trainingsites.pop_front();
> +
> +     // changing capacity
> +     if (tso.site->soldier_capacity() != 2) {
> +             game().send_player_change_soldier_capacity(*ts, 2 - 
> tso.site->soldier_capacity());
> +     }
> +
> +     ts_without_trainers_ = 0;  // zeroing
>       for (std::list<TrainingSiteObserver>::iterator site = 
> trainingsites.begin();
>            site != trainingsites.end();
>            ++site) {
>  
> -             for (uint32_t k = 0; k < site->bo->inputs_.size(); ++k) {
> -                     game().send_player_set_ware_priority(
> -                        *site->site, wwWARE, site->bo->inputs_.at(k), 
> new_priority);
> +             if (!site->site->can_start_working()) {
> +                     ts_without_trainers_ += 1;
>               }
>       }
>       return true;
> @@ -3310,14 +3543,18 @@
>                               BuildableField bf(f);
>                               update_buildable_field(bf, vision, true);
>                               const int32_t size_penalty = ms->get_size() - 1;
> +                             FindNodeAllyOwned find_ally(player_, game(), 
> player_number());
> +                             const int32_t allyOwnedFields =
> +                                map.find_fields(Area<FCoords>(f, vision), 
> nullptr, find_ally);
>  
>                               int16_t score = 0;
> -                             score += (bf.military_capacity_ > 5);
> -                             score += (bf.military_presence_ > 3);
> +                             score += (bf.area_military_capacity_ > 6);
> +                             score += (bf.area_military_capacity_ > 18);
> +                             score += (bf.area_military_presence_ > 4);
>                               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);
> +                             score += (bf.military_stationed_ > 2);
> +                             score -= size_penalty;
> +                             score += ((bf.unowned_land_nearby_ + 
> allyOwnedFields) < 10);
>  
>                               if (score >= 4) {
>                                       if (ms->get_playercaps() & 
> Widelands::Building::PCap_Dismantle) {
> @@ -3340,7 +3577,6 @@
>  
>               // yes enemy is nearby, but still we must distinguish whether
>               // he is accessible (over the land)
> -
>               if (other_player_accessible(
>                      vision + 4, &unused1, &unused2, ms->get_position(), 
> WalkSearch::kOtherPlayers)) {
>  
> @@ -3502,7 +3738,10 @@
>               }
>       }
>  
> -     throw wexception("Help: I do not know what to do with a %s", name);
> +     throw wexception("Help: I (player %d / tribe %s) do not know what to do 
> with a %s",
> +                      player_number(),
> +                      tribe_->name().c_str(),
> +                      name);
>  }
>  
>  // this is called whenever we gain ownership of a PlayerImmovable
> @@ -3804,6 +4043,7 @@
>  
>  // 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());
>  
>       if (bo.type == BuildingObserver::CONSTRUCTIONSITE) {
> @@ -3817,6 +4057,17 @@
>               if (target_bo.type == BuildingObserver::MILITARYSITE) {
>                       ++num_milit_constructionsites;
>               }
> +             if (target_bo.type == BuildingObserver::MINE) {
> +                     mines_per_type[target_bo.mines_].in_construction += 1;
> +             }
> +             if (target_bo.type == BuildingObserver::TRAININGSITE) {
> +                     if (target_bo.ts_type_ == 1) {
> +                             ts_type1_const_count_ += 1;
> +                     }
> +                     if (target_bo.ts_type_ == 2) {
> +                             ts_type2_const_count_ += 1;
> +                     }
> +             }
>  
>               // Let defaultAI try to directly connect the constructionsite
>               taskDue[ScheduleTasks::kRoadCheck] = game().get_gametime();
> @@ -3852,6 +4103,9 @@
>  
>                       for (uint32_t i = 0; i < bo.inputs_.size(); ++i)
>                               ++wares.at(bo.inputs_.at(i)).consumers_;
> +
> +                     mines_per_type[bo.mines_].finished += 1;
> +
>               } else if (bo.type == BuildingObserver::MILITARYSITE) {
>                       militarysites.push_back(MilitarySiteObserver());
>                       militarysites.back().site = 
> &dynamic_cast<MilitarySite&>(b);
> @@ -3860,9 +4114,16 @@
>                       militarysites.back().enemies_nearby_ = true;
>  
>               } else if (bo.type == BuildingObserver::TRAININGSITE) {
> +                     ts_without_trainers_ += 1;
>                       trainingsites.push_back(TrainingSiteObserver());
>                       trainingsites.back().site = 
> &dynamic_cast<TrainingSite&>(b);
>                       trainingsites.back().bo = &bo;
> +                     if (bo.ts_type_ == 1) {
> +                             ts_type1_count_ += 1;
> +                     }
> +                     if (bo.ts_type_ == 2) {
> +                             ts_type2_count_ += 1;
> +                     }
>  
>               } else if (bo.type == BuildingObserver::WAREHOUSE) {
>                       ++numof_warehouses_;
> @@ -3888,6 +4149,7 @@
>  
>  // this is called whenever we lose a building
>  void DefaultAI::lose_building(const Building& b) {
> +
>       BuildingObserver& bo = get_building_observer(b.descr().name().c_str());
>  
>       if (bo.type == BuildingObserver::CONSTRUCTIONSITE) {
> @@ -3901,6 +4163,17 @@
>               if (target_bo.type == BuildingObserver::MILITARYSITE) {
>                       --num_milit_constructionsites;
>               }
> +             if (target_bo.type == BuildingObserver::MINE) {
> +                     mines_per_type[target_bo.mines_].in_construction -= 1;
> +             }
> +             if (target_bo.type == BuildingObserver::TRAININGSITE) {
> +                     if (target_bo.ts_type_ == 1) {
> +                             ts_type1_const_count_ -= 1;
> +                     }
> +                     if (target_bo.ts_type_ == 2) {
> +                             ts_type2_const_count_ -= 1;
> +                     }
> +             }
>  
>       } else {
>               --bo.cnt_built_;
> @@ -3938,6 +4211,9 @@
>                       for (uint32_t i = 0; i < bo.inputs_.size(); ++i) {
>                               --wares.at(bo.inputs_.at(i)).consumers_;
>                       }
> +
> +                     mines_per_type[bo.mines_].finished -= 1;
> +
>               } else if (bo.type == BuildingObserver::MILITARYSITE) {
>  
>                       for (std::list<MilitarySiteObserver>::iterator i = 
> militarysites.begin();
> @@ -3955,6 +4231,12 @@
>                            ++i) {
>                               if (i->site == &b) {
>                                       trainingsites.erase(i);
> +                                     if (bo.ts_type_ == 1) {
> +                                             ts_type1_count_ -= 1;
> +                                     }
> +                                     if (bo.ts_type_ == 2) {
> +                                             ts_type2_count_ -= 1;
> +                                     }
>                                       break;
>                               }
>                       }
> @@ -3999,49 +4281,21 @@
>       return supplied == bo.inputs_.size();
>  }
>  
> -/**
> - * The defaultAi "considers" via this function whether to attack an
> - * enemy, if opposing military buildings are in sight. In case of an attack 
> it
> - * sends all available forces.
> - *
> - * \returns true, if attack was started.
> - */
> -
> -bool DefaultAI::consider_attack(int32_t const gametime) {
> -
> -     // we assume that we are not attacking so we extend waitperiod
> -     // in case of attack the variable will be decreased below
> -     // this is intended to save some CPU and add randomness in attacking
> -     // and also differentiate according to type
> -     next_attack_waittime_ += gametime % 30;
> -     if (next_attack_waittime_ > 600 && type_ == DEFENSIVE) {
> -             next_attack_waittime_ = 20;
> -     }
> -     if (next_attack_waittime_ > 450 && type_ == NORMAL) {
> -             next_attack_waittime_ = 20;
> -     }
> -     if (next_attack_waittime_ > 300 && type_ == AGGRESSIVE) {
> -             next_attack_waittime_ = 20;
> -     }
> -
> -     // Only useable, if it owns at least one militarysite
> -     if (militarysites.empty()) {
> -             taskDue[ScheduleTasks::kConsiderAttack] = next_attack_waittime_ 
> * 1000 + gametime;
> -             return false;
> -     }
> -
> -     // First we iterate over all players and define which ones (if any)
> -     // are attackable (comparing overal strength)
> -     // counting players in game
> -     uint32_t plr_in_game = 0;
> +bool DefaultAI::check_enemy_sites(uint32_t const gametime) {
> +
> +     Map& map = game().map();
> +
> +     // define which players are attackable
>       std::vector<bool> player_attackable;
> -     PlayerNumber const nr_players = game().map().get_nrplayers();
> +     PlayerNumber const nr_players = map.get_nrplayers();
>       player_attackable.resize(nr_players);
> -     bool any_attackable = false;
> +     uint32_t plr_in_game = 0;
>       uint16_t const pn = player_number();
> -     std::unordered_set<uint32_t> irrelevant_immovables;
> -
> -     std::vector<ImmovableFound> target_buildings;
> +
> +     iterate_players_existing_novar(p, nr_players, game())++ plr_in_game;
> +
> +     // receiving games statistics and parsing it (reading latest entry)
> +     const Game::GeneralStatsVector& genstats = 
> game().get_general_statistics();
>  
>       // defining treshold ratio of own_strenght/enemy's_strength
>       uint32_t treshold_ratio = 100;
> @@ -4052,37 +4306,10 @@
>               treshold_ratio = 120;
>       }
>  
> -     iterate_players_existing_novar(p, nr_players, game())++ plr_in_game;
> -
> -     // receiving games statistics and parsing it (reading latest entry)
> -     const Game::GeneralStatsVector& genstats = 
> game().get_general_statistics();
> -
> -     // first we try to prevent exhaustion of military forces (soldiers)
> -     // via excessive attacking
> -     // before building an economy with mines.
> -     // 'Margin' is an difference between count of actual soldiers and
> -     // military sites to be manned.
> -     // If we have no mines yet, we need to preserve some soldiers for 
> further
> -     // expansion (if enemy allows this)
> -     // TODO(sirver): this next line is completely unreadable and maybe even 
> wrong given the
> -     // precedence of ?: and +. Replace through some if/else.
> -     int32_t needed_margin = (mines_.size() < 6) ?
> -                                ((6 - mines_.size()) * 3) :
> -                                0 + 2 + ((type_ == NORMAL) ? 4 : 0 + ((type_ 
> == DEFENSIVE) ? 8 : 0));
> -     const int32_t current_margin =
> -        genstats[pn - 1].miltary_strength.back() - militarysites.size() - 
> num_milit_constructionsites;
> -
> -     if (current_margin < needed_margin) {  // no attacking!
> -             last_attack_target_.x = std::numeric_limits<uint16_t>::max();
> -             last_attack_target_.y = std::numeric_limits<uint16_t>::max();
> -             taskDue[ScheduleTasks::kConsiderAttack] = next_attack_waittime_ 
> * 1000 + gametime;
> -             return false;
> -     }
> -
>       // now we test all players which one are 'attackable'
>       for (uint8_t j = 1; j <= plr_in_game; ++j) {
> -             if (pn == j) {
> -                     player_attackable.at(j - 1) = false;
> +             if (pn == j) {  // its me
> +                     player_attackable[j - 1] = false;
>                       continue;
>               }
>  
> @@ -4095,12 +4322,10 @@
>                               // Avoid division by zero
>                       } else if (genstats.at(j - 1).miltary_strength.back() 
> == 0) {
>                               player_attackable.at(j - 1) = true;
> -                             any_attackable = true;
>                               // Check threshold
>                       } else if ((genstats.at(pn - 1).miltary_strength.back() 
> * 100 /
>                                   genstats.at(j - 1).miltary_strength.back()) 
> > treshold_ratio) {
>                               player_attackable.at(j - 1) = true;
> -                             any_attackable = true;
>                       } else {
>                               player_attackable.at(j - 1) = false;
>                       }
> @@ -4112,147 +4337,229 @@
>               }
>       }
>  
> -     // if we cannot attack anybody, terminating...
> -     if (!any_attackable) {
> -             taskDue[ScheduleTasks::kConsiderAttack] = next_attack_waittime_ 
> * 1000 + gametime;
> -             last_attack_target_.x = std::numeric_limits<uint16_t>::max();
> -             last_attack_target_.y = std::numeric_limits<uint16_t>::max();
> -             return false;
> -     }
> -
> -     // the logic of attacking is to pick n own military buildings - random 
> ones
> -     // and test the vicinity for attackable buildings
> -     // candidates are put into target_buildings vector for later processing
> -     const uint16_t test_every = 4;
> -     Map& map = game().map();
> -     MilitarySite* best_ms_target = nullptr;
> -     Warehouse* best_wh_target = nullptr;
> -     int32_t best_ms_score = 0;
> -     int32_t best_wh_score = 0;
> -     const int8_t minimal_difference = 2;
> -
> -     for (uint32_t position = gametime % test_every; position < 
> militarysites.size();
> -          position += test_every) {
> -
> -             std::list<MilitarySiteObserver>::iterator mso = 
> militarysites.begin();
> -             std::advance(mso, position);
> -
> -             MilitarySite* ms = mso->site;
> -
> -             if (!mso->enemies_nearby_) {
> -                     continue;
> -             }
> -
> +     // first we scan vicitnity of couple of militarysites to get new enemy 
> sites
> +     // militarysites rotate
> +     int32_t i = 0;
> +     for (MilitarySiteObserver mso : militarysites) {
> +             i += 1;
> +             if (i % 4 == 0)
> +                     continue;
> +             if (i > 20)
> +                     continue;
> +
> +             MilitarySite* ms = mso.site;
>               uint32_t const vision = ms->descr().vision_range();
>               FCoords f = map.get_fcoords(ms->get_position());
>  
>               // get list of immovable around this our military site
>               std::vector<ImmovableFound> immovables;
> -             map.find_immovables(Area<FCoords>(f, vision + 3), &immovables, 
> FindImmovableAttackable());
> +             map.find_immovables(Area<FCoords>(f, (vision + 3 < 13) ? 13 : 
> vision + 3),
> +                                 &immovables,
> +                                 FindImmovableAttackable());
>  
>               for (uint32_t j = 0; j < immovables.size(); ++j) {
> -
> -                     // skip if in irrelevant_immovables
> -                     const uint32_t hash = 
> coords_hash(immovables.at(j).coords);
> -                     if (irrelevant_immovables.count(hash) == 0) {
> -                             irrelevant_immovables.insert(hash);
> -                     }
> -
> -                     // maybe these are not good candidates to attack
> -                     if (upcast(MilitarySite, bld, immovables.at(j).object)) 
> {
> -
> -                             if 
> (!player_attackable[bld->owner().player_number() - 1]) {
> -                                     continue;
> -                             }
> -
> -                             // in case this is the same building as 
> previously attacked
> -                             if (last_attack_target_ == bld->get_position()) 
> {
> -                                     continue;
> -                             }
> -
> +                     if (upcast(MilitarySite const, bld, 
> immovables.at(j).object)) {
> +                             if (player_->is_hostile(bld->owner())) {
> +                                     if 
> (enemy_sites.count(coords_hash(bld->get_position())) == 0) {
> +                                             
> enemy_sites[coords_hash(bld->get_position())] = EnemySiteObserver();
> +                                     }
> +                             }
> +                     }
> +                     if (upcast(Warehouse const, wh, 
> immovables.at(j).object)) {
> +                             if (player_->is_hostile(wh->owner())) {
> +                                     if 
> (enemy_sites.count(coords_hash(wh->get_position())) == 0) {
> +                                             
> enemy_sites[coords_hash(wh->get_position())] = EnemySiteObserver();
> +                                     }
> +                             }
> +                     }
> +             }
> +     }
> +
> +     // now we update some of them
> +     uint32_t best_target = std::numeric_limits<uint32_t>::max();
> +     uint8_t best_score = 0;
> +     uint32_t count = 0;
> +
> +     for (std::map<uint32_t, EnemySiteObserver>::iterator site = 
> enemy_sites.begin();
> +          site != enemy_sites.end();
> +          ++site) {
> +
> +             // we test max 12 sites and prefer ones tested more then 1 min 
> ago
> +             if (((site->second.last_tested + (enemysites_check_delay_ * 
> 1000)) > gametime && count > 4) ||
> +                 count > 12) {
> +                     continue;
> +             }
> +             count += 1;
> +
> +             site->second.last_tested = gametime;
> +             uint8_t defenders = 0;
> +             bool is_warehouse = false;
> +             bool is_attackable = false;
> +             uint16_t onwer_number = 100;
> +
> +             // testing if we can attack the building - result is a flag
> +             // if we dont get a flag, we remove the building from observers 
> list
> +             FCoords f = map.get_fcoords(coords_unhash(site->first));
> +             uint32_t site_to_be_removed = 
> std::numeric_limits<uint32_t>::max();
> +             Flag* flag = nullptr;
> +             if (upcast(MilitarySite, bld, f.field->get_immovable())) {
> +                     if (player_->is_hostile(bld->owner())) {
> +                             defenders = bld->present_soldiers().size();
> +                             flag = &bld->base_flag();
>                               if (bld->can_attack()) {
> -
> -                                     int32_t attack_soldiers = 
> player_->find_attack_soldiers(bld->base_flag());
> -                                     if (attack_soldiers < 1) {
> -                                             continue;
> -                                     }
> -
> -                                     const int32_t soldiers_difference =
> -                                        
> player_->find_attack_soldiers(bld->base_flag()) - 
> bld->present_soldiers().size();
> -
> -                                     if (soldiers_difference < 
> minimal_difference)
> -                                             continue;
> -                                     if (soldiers_difference <= 
> best_ms_score)
> -                                             continue;
> -
> -                                     best_ms_target = bld;
> -                                     best_ms_score = soldiers_difference;
> -                                     continue;
> -                             }
> -                     } else if (upcast(Warehouse, wh, 
> immovables.at(j).object)) {
> -                             if (!player_->is_hostile(wh->owner())) {
> -                                     continue;
> -                             }
> -
> -                             // in case this is the same building as 
> previously attacked
> -                             if (last_attack_target_ == wh->get_position()) {
> -                                     continue;
> -                             }
> -
> -                             if (wh->can_attack()) {
> -                                     int32_t attack_soldiers = 
> player_->find_attack_soldiers(wh->base_flag());
> -                                     if (attack_soldiers < 1) {
> -                                             continue;
> -                                     }
> -
> -                                     const int32_t soldiers_difference = 
> player_->find_attack_soldiers(wh->base_flag()) -
> -                                                                         
> wh->present_soldiers().size() +
> -                                                                         3;  
> //+3 is to boost attack here
> -
> -                                     if (soldiers_difference < 
> minimal_difference)
> -                                             continue;
> -                                     if (soldiers_difference <= 
> best_wh_score)
> -                                             continue;
> -
> -                                     best_wh_target = wh;
> -                                     best_wh_score = soldiers_difference;
> -                             }
> -                     }
> -             }
> -     }
> -
> -     // we always try to attack warehouse first
> -     if (best_wh_target != nullptr && gametime % 2 == 0) {
> -             // attacking with all attack-ready soldiers
> -             int32_t attackers = 
> player_->find_attack_soldiers(best_wh_target->base_flag());
> -
> -             game().send_player_enemyflagaction(best_wh_target->base_flag(), 
> pn, attackers);
> -             last_attack_target_ = best_wh_target->get_position();
> -             taskDue[ScheduleTasks::kConsiderAttack] = (gametime % 10 + 10) 
> * 1000 + gametime;
> -             next_attack_waittime_ = 10;
> -             return true;
> -
> -     } else if (best_ms_target != nullptr) {
> -
> -             // attacking with defenders + 6 soldiers
> -             int32_t attackers = 
> player_->find_attack_soldiers(best_ms_target->base_flag());
> -             const int32_t defenders = 
> best_ms_target->present_soldiers().size();
> -             if (attackers > defenders + 10) {  // we need to leave 
> meaningful count of soldiers
> -                     // for next attack
> -                     attackers = defenders + 6;
> -             }
> -
> -             game().send_player_enemyflagaction(best_ms_target->base_flag(), 
> pn, attackers);
> -             last_attack_target_ = best_ms_target->get_position();
> -             taskDue[ScheduleTasks::kConsiderAttack] = (gametime % 10 + 10) 
> * 1000 + gametime;
> -             next_attack_waittime_ = 10;
> -             return true;
> +                                     is_attackable = true;
> +                             }
> +                             onwer_number = bld->owner().player_number();
> +                     }
> +             }
> +             if (upcast(Warehouse, Wh, f.field->get_immovable())) {
> +                     if (player_->is_hostile(Wh->owner())) {
> +                             defenders = Wh->present_soldiers().size();
> +                             flag = &Wh->base_flag();
> +                             is_warehouse = true;
> +                             if (Wh->can_attack()) {
> +                                     is_attackable = true;
> +                             }
> +                             onwer_number = Wh->owner().player_number();
> +                     }
> +             }
> +
> +             // if flag is defined it is a good taget
> +             if (flag) {
> +                     // updating some info
> +                     // updating info on mines nearby if needed
> +                     if (site->second.mines_nearby == ExtendedBool::kUnset) {
> +                             FindNodeMineable 
> find_mines_spots_nearby(game(), f.field->get_resources());
> +                             const int32_t minescount =
> +                                map.find_fields(Area<FCoords>(f, 6), 
> nullptr, find_mines_spots_nearby);
> +                             if (minescount > 0) {
> +                                     site->second.mines_nearby = 
> ExtendedBool::kTrue;
> +                             } else {
> +                                     site->second.mines_nearby = 
> ExtendedBool::kFalse;
> +                             }
> +                     }
> +
> +                     site->second.warehouse = is_warehouse;
> +
> +                     // getting rid of default
> +                     if (site->second.last_time_attackable == 
> std::numeric_limits<uint32_t>::max()) {
> +                             site->second.last_time_attackable = gametime;
> +                     }
> +
> +                     // can we attack:
> +                     if (is_attackable) {
> +                             site->second.attack_soldiers = 
> player_->find_attack_soldiers(*flag);
> +                     } else {
> +                             site->second.attack_soldiers = 0;
> +                     }
> +
> +                     site->second.defenders = defenders;
> +
> +                     if (site->second.attack_soldiers > 0) {
> +                             site->second.score = 
> site->second.attack_soldiers - site->second.defenders / 2;
> +
> +                             if (!is_warehouse)
> +                                     site->second.score -= 1;
> +
> +                             // here is some differentiation based on 
> "character" of a player
> +                             if (type_ == NORMAL) {
> +                                     site->second.score -= 1;
> +                                     site->second.score -= 
> vacant_mil_positions_ / 10;
> +                             } else if (type_ == DEFENSIVE) {
> +                                     site->second.score -= 2;
> +                                     site->second.score -= 
> vacant_mil_positions_ / 5;
> +                             } else {  //=AGRESSIVE
> +                                     site->second.score -= 
> vacant_mil_positions_ / 15;
> +                             }
> +                             if (site->second.mines_nearby == 
> ExtendedBool::kFalse) {
> +                                     site->second.score -= 1;
> +                             }
> +                             // we dont want to attack multiple players at 
> the same time too eagerly
> +                             if (onwer_number != last_attacked_player_) {
> +                                     site->second.score -= 3;
> +                             }
> +                             // if we dont have mines yet
> +                             if (mines_.size() <= 2) {
> +                                     site->second.score -= 2;
> +                             }
> +                             // also we should have at least some training 
> sites
> +                             if ((ts_type1_count_ + ts_type2_count_) == 0) {
> +                                     site->second.score -= 2;
> +                             }
> +                             // treating no attack score
> +                             if (site->second.no_attack_counter < 0) {
> +                                     site->second.score = 0;
> +                                     site->second.no_attack_counter += 1;
> +                             }
> +                     } else {
> +                             site->second.score = 0;
> +                     }  // or the score will remain 0
> +
> +                     if (site->second.score > 0 && 
> player_attackable[onwer_number - 1]) {
> +                             if (site->second.score > best_score) {
> +                                     best_score = site->second.score;
> +                                     best_target = site->first;
> +                             }
> +                     }
> +
> +                     if (site->second.attack_soldiers > 0) {
> +                             site->second.last_time_attackable = gametime;
> +                     }
> +                     if (site->second.last_time_attackable + 20 * 60 * 1000 
> < gametime) {
> +                             site_to_be_removed = site->first;
> +                     }
> +             } else {  // we dont have a flag, let remove the site from out 
> observer list
> +                     site_to_be_removed = site->first;
> +             }
> +
> +             if (site_to_be_removed < std::numeric_limits<uint32_t>::max()) {
> +                     enemy_sites.erase(site_to_be_removed);
> +                     continue;
> +             }
> +     }
> +
> +     // modifying enemysites_check_delay_,this depends on the count
> +     // of enemysites in observer
> +     if (count >= 13 && enemysites_check_delay_ < 180) {
> +             enemysites_check_delay_ += 3;
> +     }
> +     if (count < 10 && enemysites_check_delay_ > 45) {
> +             enemysites_check_delay_ -= 2;
> +     }
> +
> +     // if coordinates hash is not set
> +     if (best_target == std::numeric_limits<uint32_t>::max()) {
> +             return false;
> +     }
> +
> +     // attacking
> +     FCoords f = map.get_fcoords(coords_unhash(best_target));
> +     // setting no attack counter here
> +     // this gauranties that it will not be attacked in next 4
> +     // turns
> +     enemy_sites[best_target].no_attack_counter = -4;
> +
> +     Flag* flag = nullptr;  // flag of a building to be attacked
> +     if (upcast(MilitarySite, bld, f.field->get_immovable())) {
> +             flag = &bld->base_flag();
> +     } else if (upcast(Warehouse, Wh, f.field->get_immovable())) {
> +             flag = &Wh->base_flag();
>       } else {
> -             taskDue[ScheduleTasks::kConsiderAttack] = next_attack_waittime_ 
> * 1000 + gametime;
> -             last_attack_target_.x = std::numeric_limits<uint16_t>::max();
> -             last_attack_target_.y = std::numeric_limits<uint16_t>::max();
> +             return false;  // this should not happen
> +     }
> +
> +     // how many attack soldiers we can send?
> +     uint32_t attackers = player_->find_attack_soldiers(*flag);
> +     // Just add some randomness
> +     attackers -= gametime % 3;
> +     if (attackers <= 0) {
>               return false;
>       }
> +
> +     game().send_player_enemyflagaction(*flag, player_number(), attackers);
> +     last_attacked_player_ = flag->owner().player_number();
> +
> +     return true;
>  }
>  
>  // This runs once in 15 minutes, and adjust wares targets based on number of
> @@ -4286,7 +4593,7 @@
>  // run over dueTasks map and returns task with lower duetime
>  DefaultAI::ScheduleTasks DefaultAI::get_oldest_task(uint32_t const gametime) 
> {
>  
> -     uint32_t oldestTaskTime = gametime;             // we are looking for 
> jobs due before now
> +     uint32_t oldestTaskTime = gametime;            // we are looking for 
> jobs due before now
>       ScheduleTasks DueTask = ScheduleTasks::kIdle;  // default
>       taskDue[ScheduleTasks::kIdle] = gametime;
>  
> 
> === modified file 'src/ai/defaultai.h'
> --- src/ai/defaultai.h        2015-03-05 20:57:07 +0000
> +++ src/ai/defaultai.h        2015-03-23 21:37:01 +0000
> @@ -9,6 +9,7 @@
>   * This program is distributed in the hope that it will be useful,
>   * but WITHOUT ANY WARRANTY; without even the implied warranty of
>   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>   * GNU General Public License for more details.
>   *
>   * You should have received a copy of the GNU General Public License
> @@ -82,9 +83,9 @@
>       enum class NewShip : uint8_t {kBuilt, kFoundOnLoad};
>       enum class ScheduleTasks : uint8_t {
>               kBbuildableFieldsCheck,
> +             kMineableFieldsCheck,
>               kRoadCheck,
>               kUnbuildableFCheck,
> -             kConsiderAttack,
>               kCheckEconomies,
>               kProductionsitesStats,
>               kConstructBuilding,
> @@ -96,7 +97,9 @@
>               kPrintStats,
>               kIdle,
>               kCheckMilitarysites,
> -             kCheckTrainingsites
> +             kCheckTrainingsites,
> +             kCountMilitaryVacant,
> +             kCheckEnemySites
>       };
>       enum class MilitaryStrategy : uint8_t {
>               kNoNewMilitary,
> @@ -161,7 +164,6 @@
>                                 int16_t* max_preciousness,
>                                 int16_t* max_needed_preciousness);
>  
> -
>       ScheduleTasks get_oldest_task(uint32_t);
>  
>       bool construct_building(uint32_t);
> @@ -195,12 +197,14 @@
>       bool check_militarysites(uint32_t);
>       bool marine_main_decisions(uint32_t);
>       bool check_ships(uint32_t);
> +     bool check_enemy_sites(uint32_t);
>       void print_stats(uint32_t);
>       uint32_t get_stocklevel_by_hint(size_t);
>       uint32_t get_stocklevel(BuildingObserver&);
>       uint32_t get_warehoused_stock(Widelands::WareIndex wt);
>       uint32_t get_stocklevel(Widelands::WareIndex);  // count all direct 
> outputs_
>       void review_wares_targets(uint32_t);
> +     void count_military_vacant_positions();
>  
>       // sometimes scanning an area in radius gives inappropriate results, so 
> this is to verify that
>       // other player is accessible
> @@ -232,7 +236,7 @@
>  
>       bool check_supply(const BuildingObserver&);
>  
> -     bool consider_attack(int32_t);
> +     // bool consider_attack(int32_t);
>  
>       void print_land_stats();
>  
> @@ -252,6 +256,10 @@
>       uint32_t num_prod_constructionsites;
>       uint32_t num_ports;
>  
> +     uint16_t last_attacked_player_;
> +     // check ms in this interval - will auto-adjust
> +     uint32_t enemysites_check_delay_;
> +
>       std::list<Widelands::FCoords> unusable_fields;
>       std::list<BuildableField*> buildable_fields;
>       std::list<BlockedField> blocked_fields;
> @@ -268,6 +276,9 @@
>       std::list<TrainingSiteObserver> trainingsites;
>       std::list<ShipObserver> allships;
>       std::map<ScheduleTasks, uint32_t> taskDue;
> +     std::map<uint32_t, EnemySiteObserver> enemy_sites;
> +     // it will map mined material to observer
> +     std::map<int32_t, MineTypesObserver> mines_per_type;
>  
>       std::vector<WareObserver> wares;
>  
> @@ -284,10 +295,10 @@
>       // when territory is expanded for every candidate field benefits are 
> calculated
>       // but need for water, space, mines can vary
>       // so if 255 = resource is needed, 0 = not needed
> -     uint8_t resource_necessity_territory_;
> -     uint8_t resource_necessity_mines_;
> -     uint8_t resource_necessity_stones_;
> -     uint8_t resource_necessity_water_;
> +     int32_t resource_necessity_territory_;
> +     int32_t resource_necessity_mines_;
> +     int32_t resource_necessity_stones_;  // NOCOM
> +     int32_t resource_necessity_water_;
>       bool resource_necessity_water_needed_;  // unless atlanteans
>  
>       uint16_t unstationed_milit_buildings_;  // counts empty military 
> buildings (ones where no soldier
> @@ -295,14 +306,21 @@
>       uint16_t military_under_constr_;
>       uint16_t military_last_dismantle_;
>       uint32_t military_last_build_;  // sometimes expansions just stops, 
> this is time of last military
> -                                    // building build
> +                                     // building build
>       Widelands::Coords
> -        last_attack_target_;         // flag to abuilding (position) that 
> was attacked last time
> +        last_attack_target_;          // flag to abuilding (position) that 
> was attacked last time
>       uint32_t next_attack_waittime_;  // second till the next attack 
> consideration
> -     bool seafaring_economy;         // false by default, until first port 
> space is found
> +     bool seafaring_economy;          // false by default, until first port 
> space is found
>       uint32_t colony_scan_area_;  // distance from a possible port that is 
> scanned for owned territory
>       // it decreases with failed scans
>       int32_t spots_;  // sum of buildable fields
> +     int32_t vacant_mil_positions_;  // sum of vacant positions in 
> militarysites and training sites
> +     //statistics for training sites per type
> +     uint8_t ts_type1_count_;
> +     uint8_t ts_type1_const_count_;
> +     uint8_t ts_type2_count_;
> +     uint8_t ts_type2_const_count_;
> +     uint8_t ts_without_trainers_;
>  
>       enum {kReprioritize, kStopShipyard, kStapShipyard};
>  
> 
> === modified file 'tribes/atlanteans/dungeon/conf'
> --- tribes/atlanteans/dungeon/conf    2014-03-17 17:23:26 +0000
> +++ tribes/atlanteans/dungeon/conf    2015-03-23 21:37:01 +0000
> @@ -77,3 +77,6 @@
>  [idle]
>  pics=dungeon_i_??.png  # ???
>  hotspot=47 48
> +
> +[aihints]
> +ts_type=2

please use trainingssite_type and a string instead of an integer

> 
> === modified file 'tribes/atlanteans/labyrinth/conf'
> --- tribes/atlanteans/labyrinth/conf  2014-10-07 20:06:46 +0000
> +++ tribes/atlanteans/labyrinth/conf  2015-03-23 21:37:01 +0000
> @@ -99,4 +99,4 @@
>  hotspot=80 88
>  
>  [aihints]
> -prohibited_till=2700
> +ts_type=1
> 
> === modified file 'tribes/barbarians/battlearena/conf'
> --- tribes/barbarians/battlearena/conf        2014-07-29 09:27:08 +0000
> +++ tribes/barbarians/battlearena/conf        2015-03-23 21:37:01 +0000
> @@ -74,3 +74,6 @@
>  pics=battlearena_w_??.png  # ???
>  hotspot=110 72
>  fps=10
> +
> +[aihints]
> +ts_type=1
> 
> === modified file 'tribes/barbarians/trainingcamp/conf'
> --- tribes/barbarians/trainingcamp/conf       2014-09-24 21:06:00 +0000
> +++ tribes/barbarians/trainingcamp/conf       2015-03-23 21:37:01 +0000
> @@ -36,7 +36,7 @@
>  max_level=4
>  
>  [aihints]
> -prohibited_till=2700
> +ts_type=2
>  
>  [soldier hp]
>  min_level=0
> 
> === modified file 'tribes/empire/arena/conf'
> --- tribes/empire/arena/conf  2014-09-30 08:05:35 +0000
> +++ tribes/empire/arena/conf  2015-03-23 21:37:01 +0000
> @@ -54,3 +54,6 @@
>  [build]
>  pics=arena_b_??.png  # ???
>  hotspot=82 83
> +
> +[aihints]
> +ts_type=1
> 
> === modified file 'tribes/empire/colosseum/conf'
> --- tribes/empire/colosseum/conf      2014-09-30 08:05:35 +0000
> +++ tribes/empire/colosseum/conf      2015-03-23 21:37:01 +0000
> @@ -60,3 +60,6 @@
>  [idle]
>  pics=colosseum_i_??.png  # ???
>  hotspot=81 106
> +
> +[aihints]
> +ts_type=1
> 
> === modified file 'tribes/empire/piggery/conf'
> --- tribes/empire/piggery/conf        2014-08-02 19:55:23 +0000
> +++ tribes/empire/piggery/conf        2015-03-23 21:37:01 +0000
> @@ -2,6 +2,7 @@
>  output=meat
>  
>  [aihints]
> +forced_after=9000
>  
>  [buildcost]
>  log=2
> 
> === modified file 'tribes/empire/trainingcamp/conf'
> --- tribes/empire/trainingcamp/conf   2014-08-02 19:55:23 +0000
> +++ tribes/empire/trainingcamp/conf   2015-03-23 21:37:01 +0000
> @@ -127,4 +127,4 @@
>  hotspot=82 105
>  
>  [aihints]
> -prohibited_till=2700
> +ts_type=2
> 


-- 
https://code.launchpad.net/~widelands-dev/widelands/ai-military-changes/+merge/253881
Your team Widelands Developers is subscribed to branch 
lp:~widelands-dev/widelands/ai-military-changes.

_______________________________________________
Mailing list: https://launchpad.net/~widelands-dev
Post to     : widelands-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~widelands-dev
More help   : https://help.launchpad.net/ListHelp

Reply via email to