widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #02549
[Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
Tibor Bamhor has proposed merging lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands.
Requested reviews:
Widelands Developers (widelands-dev)
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/tibor-ai5/+merge/228762
Another chunk of improvements to AI:
Reworked building construction prioritization/scoring - simplification of code, attention to early stages of game, also when AI starts with Fortified Village. Also I added new aihints prohibited_till and forced_after to add more control over building of buildings at the begining of game. They supersede some other ai hints (and these was removed).
Changes to military - fixed bug, when big space migh have been left without military buildings. Fixed a bug when AI did not increase number of soldiers when needed (enemy nearby). More simplified expansion control, now AI sets itself into 4 modes: FreeExpansion/EnemyOrResources/EnemyOnly/NoNewMilitaryBuildings - to prevent big number of buildings in construction and better focusing of resources where needed.
For first time I was doing benchmarks (the game stops after 150 min and prints out the land size and military strength of all players) - I measured it when I made changes, but also to compare performance of tribes x starting mode.
Making roads (network of roads) more sparse - as they occupied too many fields and was usually not utilized.
Fixing any other small problems whenever I run into and code housekeeping.
--
https://code.launchpad.net/~widelands-dev/widelands/tibor-ai5/+merge/228762
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands.
=== modified file 'src/ai/ai_help_structs.h'
--- src/ai/ai_help_structs.h 2014-07-28 16:59:54 +0000
+++ src/ai/ai_help_structs.h 2014-07-29 20:53:33 +0000
@@ -137,7 +137,6 @@
const World& world_;
};
-
struct FindNodeWithFlagOrRoad {
Economy* economy;
bool accept(const Map&, FCoords) const;
@@ -166,6 +165,14 @@
}
};
+// usually we order by shortest shortcut, but sometimes it makes sense to
+// make shortcut by biggest road reduction
+struct CompareShortening {
+ bool operator()(const NearFlag& a, const NearFlag& b) const {
+ return (a.cost_ - a.distance_) > (b.cost_ - b.distance_);
+ }
+};
+
struct WalkableSpot {
Coords coords;
bool has_flag_;
@@ -220,6 +227,10 @@
int16_t military_presence_;
// stationed (manned) military buildings nearby
int16_t military_stationed_;
+ // some buildings must be postponed bit
+ int32_t prohibited_till_;
+ // and then some must be forced
+ int32_t forced_after_;
std::vector<uint8_t> consumers_nearby_;
std::vector<uint8_t> producers_nearby_;
@@ -296,22 +307,22 @@
MINE
} type;
- bool is_basic_; // is a "must" to have for the ai
- bool is_food_basic_; // few food producer to be built sooner
bool prod_build_material_;
bool plants_trees_;
bool recruitment_; // is "producing" workers?
bool is_buildable_;
bool need_trees_; // lumberjack = true
bool need_stones_; // quarry = true
- bool mines_marble_; // need to distinquish mines_ that produce marbles
bool mines_water_; // wells
bool need_water_; // fisher, fish_breeder = true
bool is_hunter_; // need to identify hunters
+ bool is_fisher_; // need to identify hunters
bool space_consumer_; // farm, vineyard... = true
bool expansion_type_; // military building used that can be used to control area
bool fighting_type_; // military building built near enemies
bool mountain_conqueror_; // military building built near mountains
+ int32_t prohibited_till_; // do not build before (ms)
+ int32_t forced_after_; // do not wait until ware is needed
bool unoccupied_; //
=== modified file 'src/ai/ai_hints.cc'
--- src/ai/ai_hints.cc 2014-07-14 10:45:44 +0000
+++ src/ai/ai_hints.cc 2014-07-29 20:53:33 +0000
@@ -32,12 +32,8 @@
BuildingHints::BuildingHints(Section* const section)
: renews_map_resource(nullptr),
mines_(nullptr),
- basic_(section ? section->get_bool("is_basic") : false),
- food_basic_(section ? section->get_bool("is_food_basic") : false),
- build_material_(section ? section->get_bool("build_material") : true),
log_producer_(section ? section->get_bool("logproducer") : false),
stone_producer_(section ? section->get_bool("stoneproducer") : false),
- marble_producer_(section ? section->get_bool("marbleproducer") : false),
needs_water_(section ? section->get_bool("needs_water") : false),
mines_water_(section ? section->get_bool("mines_water") : false),
recruitment_(section ? section->get_bool("recruitment") : false),
@@ -45,6 +41,8 @@
expansion_(section ? section->get_bool("expansion") : false),
fighting_(section ? section->get_bool("fighting") : false),
mountain_conqueror_(section ? section->get_bool("mountain_conqueror") : false),
+ prohibited_till_(section ? section->get_int("prohibited_till", 0) : 0),
+ forced_after_(section ? section->get_int("forced_after", 864000) : 0), // 10 days default
mines_percent_(section ? section->get_int("mines_percent", 100) : 0) {
if (section) {
if (char const* const s = section->get_string("renews_map_resource"))
=== modified file 'src/ai/ai_hints.h'
--- src/ai/ai_hints.h 2014-07-15 05:12:37 +0000
+++ src/ai/ai_hints.h 2014-07-29 20:53:33 +0000
@@ -41,18 +41,6 @@
return mines_;
}
- bool is_basic() const {
- return basic_;
- }
-
- bool is_food_basic() const {
- return food_basic_;
- }
-
- bool prod_build_material() const {
- return build_material_;
- }
-
bool is_logproducer() const {
return log_producer_;
}
@@ -61,10 +49,6 @@
return stone_producer_;
}
- bool is_marbleproducer() const {
- return marble_producer_;
- }
-
bool mines_water() const {
return mines_water_;
}
@@ -90,6 +74,14 @@
return mountain_conqueror_;
}
+ int32_t get_prohibited_till() const {
+ return prohibited_till_;
+ }
+
+ int32_t get_forced_after() const {
+ return forced_after_;
+ }
+
uint8_t get_mines_percent() const {
return mines_percent_;
}
@@ -97,12 +89,8 @@
private:
char* renews_map_resource;
char* mines_;
- bool basic_;
- bool food_basic_;
- bool build_material_; // whether the building produces build material
bool log_producer_;
bool stone_producer_;
- bool marble_producer_;
bool needs_water_;
bool mines_water_;
bool recruitment_; // whether building recruits special workers
@@ -110,6 +98,8 @@
bool expansion_;
bool fighting_;
bool mountain_conqueror_;
+ int32_t prohibited_till_;
+ int32_t forced_after_;
uint8_t mines_percent_;
DISALLOW_COPY_AND_ASSIGN(BuildingHints);
=== modified file 'src/ai/computer_player.cc'
--- src/ai/computer_player.cc 2014-07-23 20:12:17 +0000
+++ src/ai/computer_player.cc 2014-07-29 20:53:33 +0000
@@ -21,25 +21,26 @@
#include "ai/defaultai.h"
-Computer_Player::Computer_Player
- (Widelands::Game & g, Widelands::Player_Number const pid)
- : m_game(g), m_player_number(pid)
-{
+Computer_Player::Computer_Player(Widelands::Game& g, Widelands::Player_Number const pid)
+ : m_game(g), m_player_number(pid) {
}
-Computer_Player::~Computer_Player() {}
+Computer_Player::~Computer_Player() {
+}
struct EmptyAI : Computer_Player {
- EmptyAI(Widelands::Game & g, const Widelands::Player_Number pid)
- : Computer_Player(g, pid) {}
+ EmptyAI(Widelands::Game& g, const Widelands::Player_Number pid) : Computer_Player(g, pid) {
+ }
- void think() override {}
+ void think() override {
+ }
struct EmptyAIImpl : Implementation {
- EmptyAIImpl() {name = _("None");}
- Computer_Player * instantiate
- (Widelands::Game & g, Widelands::Player_Number const pid) const override
- {
+ EmptyAIImpl() {
+ name = _("None");
+ }
+ Computer_Player* instantiate(Widelands::Game& g,
+ Widelands::Player_Number const pid) const override {
return new EmptyAI(g, pid);
}
};
@@ -49,10 +50,8 @@
EmptyAI::EmptyAIImpl EmptyAI::implementation;
-const Computer_Player::ImplementationVector &
-Computer_Player::getImplementations()
-{
- static std::vector<Computer_Player::Implementation const *> impls;
+const Computer_Player::ImplementationVector& Computer_Player::getImplementations() {
+ static std::vector<Computer_Player::Implementation const*> impls;
if (impls.empty()) {
impls.push_back(&DefaultAI::aggressiveImpl);
@@ -64,10 +63,8 @@
return impls;
}
-const Computer_Player::Implementation * Computer_Player::getImplementation
- (const std::string & name)
-{
- const ImplementationVector & vec = getImplementations();
+const Computer_Player::Implementation* Computer_Player::getImplementation(const std::string& name) {
+ const ImplementationVector& vec = getImplementations();
for (const Computer_Player::Implementation* implementation : vec) {
if (implementation->name == name) {
=== modified file 'src/ai/computer_player.h'
--- src/ai/computer_player.h 2014-07-16 08:23:42 +0000
+++ src/ai/computer_player.h 2014-07-29 20:53:33 +0000
@@ -36,14 +36,19 @@
* Instances of actual AI implementation can be created via the
* \ref Implementation interface.
*/
+
struct Computer_Player {
- Computer_Player(Widelands::Game &, const Widelands::Player_Number);
+ Computer_Player(Widelands::Game&, const Widelands::Player_Number);
virtual ~Computer_Player();
- virtual void think () = 0;
+ virtual void think() = 0;
- Widelands::Game & game() const {return m_game;}
- Widelands::Player_Number player_number() {return m_player_number;}
+ Widelands::Game& game() const {
+ return m_game;
+ }
+ Widelands::Player_Number player_number() {
+ return m_player_number;
+ }
/**
* Interface to a concrete implementation, used to instantiate AIs.
@@ -52,26 +57,24 @@
*/
struct Implementation {
std::string name;
- virtual ~Implementation() {}
- virtual Computer_Player * instantiate
- (Widelands::Game &, Widelands::Player_Number) const = 0;
+ virtual ~Implementation() {
+ }
+ virtual Computer_Player* instantiate(Widelands::Game&, Widelands::Player_Number) const = 0;
};
- typedef
- std::vector<Computer_Player::Implementation const *>
- ImplementationVector;
+ typedef std::vector<Computer_Player::Implementation const*> ImplementationVector;
/**
* Get a list of available AI implementations.
*/
- static const ImplementationVector & getImplementations();
+ static const ImplementationVector& getImplementations();
/**
* Get the best matching implementation for this name.
*/
- static const Implementation * getImplementation(const std::string & name);
+ static const Implementation* getImplementation(const std::string& name);
private:
- Widelands::Game & m_game;
+ Widelands::Game& m_game;
Widelands::Player_Number const m_player_number;
DISALLOW_COPY_AND_ASSIGN(Computer_Player);
=== modified file 'src/ai/defaultai.cc'
--- src/ai/defaultai.cc 2014-07-28 18:03:51 +0000
+++ src/ai/defaultai.cc 2014-07-29 20:53:33 +0000
@@ -44,16 +44,18 @@
#include "logic/world/world.h"
#include "profile/profile.h"
+// Building of new military buildings can be restricted
+constexpr int kFreeExpansion = 1;
+constexpr int kResourcesOrDefense = 2;
+constexpr int kDefenseOnly = 3;
+constexpr int kNoNewMilitary = 4;
+
// following is in miliseconds (widelands counts time in ms)
constexpr int kFieldUpdateInterval = 1000;
constexpr int kIdleMineUpdateInterval = 22000;
constexpr int kBusyMineUpdateInterval = 2000;
// building of the same building can be started after 25s at earliest
constexpr int kBuildingMinInterval = 25 * 1000;
-constexpr int kBaseInfrastructureTime = 20 * 60 * 1000;
-// buildings marked as is_food_basic will be forced after 15 minutes, even though their outputs are
-// not needed yet
-constexpr int kPrimaryFoodStartTime = 15 * 60 * 1000;
using namespace Widelands;
@@ -70,6 +72,8 @@
player_(nullptr),
tribe_(nullptr),
num_constructionsites_(0),
+ num_milit_constructionsites(0),
+ num_prod_constructionsites(0),
next_road_due_(2000),
next_stats_update_due_(30000),
next_construction_due_(1000),
@@ -81,35 +85,36 @@
next_helpersites_check_due_(180000),
inhibit_road_building_(0),
time_of_last_construction_(0),
+ enemy_last_seen_(-2 * 60 * 1000),
numof_warehouses_(0),
new_buildings_stop_(false),
unstationed_milit_buildings_(0),
- military_under_constr_(0),
military_last_dismantle_(0),
- military_last_build_(0) {
+ military_last_build_(0),
+ spots_(0) {
// Subscribe to NoteFieldPossession.
field_possession_subscriber_ =
- Notifications::subscribe<NoteFieldPossession>([this](const NoteFieldPossession& note) {
+ Notifications::subscribe<NoteFieldPossession>([this](const NoteFieldPossession& note) {
if (note.player != player_) {
- return;
- }
+ return;
+ }
if (note.ownership == NoteFieldPossession::Ownership::GAINED) {
- unusable_fields.push_back(note.fc);
- }
+ unusable_fields.push_back(note.fc);
+ }
});
// Subscribe to NoteImmovables.
immovable_subscriber_ =
- Notifications::subscribe<NoteImmovable>([this](const NoteImmovable& note) {
+ Notifications::subscribe<NoteImmovable>([this](const NoteImmovable& note) {
if (note.pi->owner().player_number() != player_->player_number()) {
- return;
- }
+ return;
+ }
if (note.ownership == NoteImmovable::Ownership::GAINED) {
- gain_immovable(*note.pi);
- } else {
- lose_immovable(*note.pi);
- }
+ gain_immovable(*note.pi);
+ } else {
+ lose_immovable(*note.pi);
+ }
});
}
@@ -212,8 +217,6 @@
// actions are. Reasons are the following:
// * The "donkey feature" made economies more stable, even with stupid
// roads.
- // * If defaultAI builds too much roads, it will waste good building
- // space.
if (improve_roads(gametime)) {
m_buildable_changed = true;
m_mineable_changed = true;
@@ -267,12 +270,9 @@
bo.production_hint_ = -1;
bo.current_stats_ = 0;
bo.unoccupied_ = false;
- bo.is_basic_ = false;
- bo.is_food_basic_ = false;
bo.is_buildable_ = bld.is_buildable();
bo.need_trees_ = bh.is_logproducer();
bo.need_stones_ = bh.is_stoneproducer();
- bo.mines_marble_ = bh.is_marbleproducer();
bo.need_water_ = bh.get_needs_water();
bo.mines_water_ = bh.mines_water();
bo.recruitment_ = bh.for_recruitment();
@@ -280,9 +280,10 @@
bo.expansion_type_ = bh.is_expansion_type();
bo.fighting_type_ = bh.is_fighting_type();
bo.mountain_conqueror_ = bh.is_mountain_conqueror();
+ bo.prohibited_till_ = bh.get_prohibited_till() * 1000; // value in conf is in seconds
+ bo.forced_after_ = bh.get_forced_after() * 1000; // value in conf is in seconds
if (char const* const s = bh.get_renews_map_resource()) {
bo.production_hint_ = tribe_->safe_ware_index(s);
-
}
// I just presume cut wood is named "log" in the game
@@ -311,16 +312,17 @@
bo.mines_percent_ = bh.get_mines_percent();
}
- bo.is_basic_ = bh.is_basic();
- bo.is_food_basic_ = bh.is_food_basic();
- bo.prod_build_material_ = bh.prod_build_material();
-
// here we identify hunters
if (bo.outputs_.size() == 1 && tribe_->safe_ware_index("meat") == bo.outputs_.at(0)) {
bo.is_hunter_ = true;
} else
bo.is_hunter_ = false;
+ // and fishers
+ if (bo.outputs_.size() == 1 && tribe_->safe_ware_index("fish") == bo.outputs_.at(0)) {
+ bo.is_fisher_ = true;
+ } else
+ bo.is_fisher_ = false;
continue;
}
@@ -346,6 +348,8 @@
}
num_constructionsites_ = 0;
+ num_milit_constructionsites = 0;
+ num_prod_constructionsites = 0;
next_construction_due_ = 0;
next_road_due_ = 1000;
next_productionsite_check_due_ = 0;
@@ -554,8 +558,8 @@
map.get_neighbour(field.coords, WALK_SE, &fse);
if (BaseImmovable const* const imm = fse.field->get_immovable())
- if (dynamic_cast<Flag const*>(imm)
- || (dynamic_cast<Road const*>(imm) && (fse.field->nodecaps() & BUILDCAPS_FLAG)))
+ if (dynamic_cast<Flag const*>(imm) ||
+ (dynamic_cast<Road const*>(imm) && (fse.field->nodecaps() & BUILDCAPS_FLAG)))
field.preferred_ = true;
for (uint32_t i = 0; i < immovables.size(); ++i) {
@@ -571,6 +575,7 @@
if (player_immovable->owner().player_number() != pn) {
if (player_->is_hostile(player_immovable->owner()))
field.enemy_nearby_ = true;
+ enemy_last_seen_ = game().get_gametime();
continue;
}
@@ -588,7 +593,9 @@
if (dynamic_cast<const ProductionSite*>(building))
consider_productionsite_influence(
- field, immovables.at(i).coords, get_building_observer(building->descr().name().c_str()));
+ field,
+ immovables.at(i).coords,
+ get_building_observer(building->descr().name().c_str()));
}
if (immovables.at(i).object->has_attribute(tree_attr))
@@ -616,7 +623,12 @@
}
// folowing is done allways (regardless of military or not)
+
field.military_stationed_ = 0;
+ field.military_in_constr_nearby_ = 0;
+ field.military_capacity_ = 0;
+ field.military_loneliness_ = 1000;
+ field.military_presence_ = 0;
for (uint32_t i = 0; i < immovables.size(); ++i) {
const BaseImmovable& base_immovable = *immovables.at(i).object;
@@ -644,7 +656,8 @@
const int32_t v = radius - dist;
if (v > 0) {
- field.military_capacity_ += 2;
+ field.military_capacity_ += target_ms_d->get_max_number_of_soldiers() / 2 + 1;
+ // field.military_capacity_ += 2;
field.military_loneliness_ *= static_cast<double_t>(dist) / radius;
field.military_in_constr_nearby_ += 1;
}
@@ -663,14 +676,15 @@
if (!militarysite->stationedSoldiers().empty()) {
field.military_stationed_ += 1;
- }
+ } else
+ // the name does not match much
+ field.military_in_constr_nearby_ += 1;
field.military_loneliness_ *= static_cast<double_t>(dist) / radius;
}
}
}
}
-
}
/// Updates one mineable field
@@ -686,8 +700,8 @@
map.get_brn(field.coords, &fse);
if (BaseImmovable const* const imm = fse.field->get_immovable())
- if (dynamic_cast<Flag const*>(imm)
- || (dynamic_cast<Road const*>(imm) && (fse.field->nodecaps() & BUILDCAPS_FLAG)))
+ if (dynamic_cast<Flag const*>(imm) ||
+ (dynamic_cast<Road const*>(imm) && (fse.field->nodecaps() & BUILDCAPS_FLAG)))
field.preferred_ = true;
for (const ImmovableFound& temp_immovable : immovables) {
@@ -779,7 +793,6 @@
// Just used for easy checking whether a mine or something else was built.
bool mine = false;
bool field_blocked = false;
- int32_t spots = 0;
uint32_t consumers_nearby_count = 0;
// this is to increase score so also building near borders can be built
int32_t bulgarian_constant = 12;
@@ -795,53 +808,47 @@
++i)
++spots_avail.at((*i)->coords.field->nodecaps() & BUILDCAPS_SIZEMASK);
- spots = spots_avail.at(BUILDCAPS_SMALL);
- spots += spots_avail.at(BUILDCAPS_MEDIUM);
- spots += spots_avail.at(BUILDCAPS_BIG);
+ spots_ = spots_avail.at(BUILDCAPS_SMALL);
+ spots_ += spots_avail.at(BUILDCAPS_MEDIUM);
+ spots_ += spots_avail.at(BUILDCAPS_BIG);
- // checking amount of free spots, if needed setting new building stop flag
+ // here we possible stop building of new buildings
new_buildings_stop_ = false;
+ uint8_t expansion_mode = kFreeExpansion;
- if ((militarysites.size() * 2 + 20) <
- productionsites.size()
- || spots<(3 + (static_cast<int32_t>(productionsites.size()) / 5)) || num_constructionsites_>(
- (militarysites.size() + productionsites.size()) / 2)) {
- new_buildings_stop_ = true;
+ // there are couple of reasons why to stop building production buildings
+ //(note there are numberous exemptions to this stop)
+ // 1. to not have too many constructionsites
+ if (num_prod_constructionsites > productionsites.size() / 8 + 5) {
+ new_buildings_stop_ = true;
+ }
+ // 2. to not exhaust all free spots
+ if (spots_ * 3 / 2 + 5 < static_cast<int32_t>(productionsites.size())) {
+ new_buildings_stop_ = true;
+ }
+ // 3. too keep some proportions production sites vs military sites
+ if ((num_prod_constructionsites + productionsites.size()) >
+ (num_milit_constructionsites + militarysites.size()) * 3) {
+ new_buildings_stop_ = true;
+ }
+ // BUT if enemy is nearby, we cancel above stop
+ if (new_buildings_stop_ && enemy_last_seen_ + 2 * 60 * 1000 > gametime) {
+ new_buildings_stop_ = false;
}
// sometimes there is to many military buildings in construction, so we must
// prevent initialization of further buildings start
- bool new_military_buildings_stop = false;
- // in areas close to enemies, above limit is not effective, so we have second one
- // more benevolent limit
- bool near_enemy_b_buildings_stop = false;
- // in some situation expansion just halts because there are not good spots to expand
- // so this is a boost to increase a score and allow building a military building on a spot
- // that is normally not suitable for building
- int32_t military_boost = 1;
-
- int32_t treshold = (militarysites.size() + productionsites.size()) / 100 + 1;
-
- if (unstationed_milit_buildings_ + military_under_constr_ / 3 > treshold) {
- new_military_buildings_stop = true;
-
- }
-
- if (unstationed_milit_buildings_ + military_under_constr_ / 3 > 2 * treshold) {
- near_enemy_b_buildings_stop = true;
-
- }
-
- // here we deal with situation when for some time no new military building was built
- // in fact this is a last time when there were any military buildings in construction
- if ((unstationed_milit_buildings_ + military_under_constr_) > 0)
- military_last_build_ = game().get_gametime();
-
- if (military_last_build_ + 1 * 60 * 1000 < game().get_gametime()) {
- military_boost = 200;
- }
-
- // Building_Index proposed_building = INVALID_INDEX; // I need BuildingObserver not index
+ const uint32_t treshold = militarysites.size() / 30 + 3;
+
+ if (unstationed_milit_buildings_ + num_milit_constructionsites > 3 * treshold)
+ expansion_mode = kNoNewMilitary;
+ else if (unstationed_milit_buildings_ + num_milit_constructionsites > 2 * treshold)
+ expansion_mode = kDefenseOnly;
+ else if (unstationed_milit_buildings_ + num_milit_constructionsites > 1 * treshold)
+ expansion_mode = kResourcesOrDefense;
+ else
+ expansion_mode = kFreeExpansion;
+
BuildingObserver* best_building = nullptr;
int32_t proposed_priority = 0;
Coords proposed_coords;
@@ -893,13 +900,24 @@
if (!bo.buildable(*player_))
continue;
- if (time(nullptr) % 3 == 0)
+ if (bo.prohibited_till_ > gametime) {
+ continue;
+ }
+
+ // if current field is not big enough
+ if (bo.desc->get_size() > maxsize)
+ continue;
+
+ if (time(nullptr) % 3 == 0 && bo.total_count() > 0)
continue; // add randomnes and ease AI
if (bo.type == BuildingObserver::MINE)
continue;
- if (gametime - bo.construction_decision_time_ < kBuildingMinInterval)
+ // here we do an exemption for lumberjacs, mainly in early stages of game
+ // sometimes the first one is not built and AI waits too long for second attempt
+ if (gametime - bo.construction_decision_time_ <
+ kBuildingMinInterval && !bo.need_trees_)
continue;
if (bo.unoccupied_)
@@ -932,26 +950,21 @@
if (wares.at(bo.outputs_.at(m)).preciousness_ > max_needed_preciousness)
max_needed_preciousness = wares.at(bo.outputs_.at(m)).preciousness_;
+ }
+ if (wares.at(bo.outputs_.at(m)).preciousness_ > max_preciousness)
max_preciousness = wares.at(bo.outputs_.at(m)).preciousness_;
- } else {
- if (wares.at(bo.outputs_.at(m)).preciousness_ > max_preciousness)
- max_preciousness = wares.at(bo.outputs_.at(m)).preciousness_;
- }
}
}
}
int32_t prio = 0; // score of a bulding on a field
- // if current field is not big enough
- if (bo.desc->get_size() > maxsize)
- continue;
-
if (bo.type == BuildingObserver::PRODUCTIONSITE) {
// exclude spots on border
- if (bf->near_border_ && !bo.need_trees_ && !bo.need_stones_)
+ if (bf->near_border_ && !bo.need_trees_ && !bo.need_stones_ &&
+ !bo.is_fisher_)
continue;
// this can be only a well (as by now)
@@ -961,32 +974,50 @@
if (bo.cnt_under_construction_ + bo.unoccupied_ > 0)
continue;
- if ((bo.cnt_built_ + bo.unoccupied_) > 0 && gametime < kBaseInfrastructureTime)
- continue;
- if (new_buildings_stop_)
- continue;
- bo.cnt_target_ =
- 2 + static_cast<int32_t>(mines_.size() + productionsites.size()) / 20;
- if ((bo.cnt_built_ + bo.cnt_under_construction_ + bo.unoccupied_) > bo.cnt_target_)
- continue;
+
+ prio = 0;
+ // one well has an axemption from the stop - if forced
+ if (bo.forced_after_ < gametime && bo.total_count() == 0)
+ prio = 200; // boost for first/only well
+ else if (new_buildings_stop_)
+ continue;
+
+ bo.cnt_target_ = 1;
if (bo.stocklevel_time < game().get_gametime() - 30 * 1000) {
bo.stocklevel_ = get_stocklevel(bo);
bo.stocklevel_time = game().get_gametime();
}
- if (bo.stocklevel_ > 50)
+ if (bo.stocklevel_ > 30)
continue;
- prio = bf->ground_water_ - 2;
+ prio += bf->ground_water_ - 2;
prio = recalc_with_border_range(*bf, prio);
} else if (bo.need_trees_) { // LUMBERJACS
- if (bo.cnt_built_ + bo.cnt_under_construction_ + bo.unoccupied_ <= 2)
- prio = bulgarian_constant + 200 + bf->trees_nearby_;
- else if (bo.cnt_under_construction_ + bo.unoccupied_ <= 1) {
- prio =
- bf->trees_nearby_ - 5 - bf->producers_nearby_.at(bo.outputs_.at(0)) * 5 -
- new_buildings_stop_ * 15; //+ bf->producers_nearby_.at(bo.outputs_.at(0))*5;
+ if (bo.total_count() == 0)
+ prio = 500 + bf->trees_nearby_;
+
+ else if (bo.total_count() == 1)
+ prio = 400 + bf->trees_nearby_;
+
+ else if (bf->trees_nearby_ < 2)
+ continue;
+
+ else {
+ bo.cnt_target_ =
+ 2 + static_cast<int32_t>(mines_.size() + productionsites.size()) / 20;
+
+ if (bo.total_count() < bo.cnt_target_)
+ prio = 75;
+ else
+ prio = 0;
+
+ prio += bf->trees_nearby_ - 5 - bf->producers_nearby_.at(bo.outputs_.at(0)) * 5 -
+ new_buildings_stop_ * 15;
+
+ if (bf->near_border_)
+ prio = prio / 2;
}
} else if (bo.need_stones_) {
@@ -998,20 +1029,56 @@
continue;
prio = bf->stones_nearby_;
+ if (prio <= 0)
+ continue;
+
+ if (bo.total_count() == 0)
+ prio += 150;
+
if (bo.stocklevel_time < game().get_gametime() - 5 * 1000) {
bo.stocklevel_ = get_stocklevel_by_hint(static_cast<size_t>(bo.production_hint_));
bo.stocklevel_time = game().get_gametime();
}
- if (bo.stocklevel_ < 20)
- prio = prio * 2;
-
- if (bo.total_count() == 0)
- prio = prio * 5;
+ if (bo.stocklevel_ == 0)
+ prio *= 2;
// to prevent to many quaries on one spot
prio = prio - 50 * bf->producers_nearby_.at(bo.outputs_.at(0));
+ if (bf->near_border_)
+ prio = prio / 2;
+
+ } else if (bo.is_hunter_) {
+ if (bf->critters_nearby_ < 5)
+ continue;
+
+ if (new_buildings_stop_)
+ continue;
+
+ prio +=
+ (bf->critters_nearby_ * 2) - 8 - 5 * bf->producers_nearby_.at(bo.outputs_.at(0));
+
+ } else if (bo.is_fisher_) { // fisher
+ if (bf->water_nearby_ < 5)
+ continue;
+
+ if (new_buildings_stop_)
+ continue;
+
+ if (bo.stocklevel_time < game().get_gametime() - 5 * 1000) {
+ bo.stocklevel_ = get_stocklevel_by_hint(static_cast<size_t>(bo.production_hint_));
+ bo.stocklevel_time = game().get_gametime();
+ }
+
+ if (bo.stocklevel_ > 50 && !output_is_needed)
+ continue;
+
+ if (bf->producers_nearby_.at(bo.outputs_.at(0)) >= 1)
+ continue;
+
+ prio = bf->fish_nearby_;
+
} else if (bo.production_hint_ >= 0) {
// first setting targets (needed also for dismantling)
if (bo.plants_trees_)
@@ -1032,69 +1099,64 @@
if (bo.plants_trees_) { // RANGERS
// if there are too many trees nearby
- if (bf->trees_nearby_ > 25 && bo.total_count() >= 2)
+ if (bf->trees_nearby_ > 25 && bo.total_count() >= 1)
continue;
// sometimes all area is blocked by trees so this is to prevent this
if (buildable_fields.size() < 4)
continue;
- // prevent too many rangers
- if (bo.total_count() * 3 > static_cast<int32_t>(productionsites.size()))
- continue;
-
- if (bo.stocklevel_time < game().get_gametime() - 5 * 1000) {
- bo.stocklevel_ =
- get_stocklevel_by_hint(static_cast<size_t>(bo.production_hint_));
- bo.stocklevel_time = game().get_gametime();
- }
- prio = 0;
- // if we need wood
- if (bo.stocklevel_ < 50)
- prio =
- (50 - bo.stocklevel_) + bf->producers_nearby_.at(bo.production_hint_) * 5;
-
- // if we just need some rangers to be on safe side
- if (bo.total_count() < 2)
- prio += (60 - bf->trees_nearby_) * 3 +
- bf->producers_nearby_.at(bo.production_hint_) * 5;
- else if (bo.total_count() < bo.cnt_target_)
- prio += 30 + bf->producers_nearby_.at(bo.production_hint_) * 5;
-
- } else if (gametime > kBaseInfrastructureTime &&
- !new_buildings_stop_) { // gamekeepers or so
- if (bo.stocklevel_time < game().get_gametime() - 5 * 1000) {
- bo.stocklevel_ =
- get_stocklevel_by_hint(static_cast<size_t>(bo.production_hint_));
- bo.stocklevel_time = game().get_gametime();
- }
+ if (bo.stocklevel_time < game().get_gametime() - 5 * 1000) {
+ bo.stocklevel_ =
+ get_stocklevel_by_hint(static_cast<size_t>(bo.production_hint_));
+ bo.stocklevel_time = game().get_gametime();
+ }
+
+ if (bo.total_count() == 0)
+ prio = 200;
+ if (bo.total_count() > 2 * bo.cnt_target_)
+ continue;
+ // we can go above target if there is shortage of logs on stock
+ else if (bo.total_count() > bo.cnt_target_ && bo.stocklevel_ > 40)
+ continue;
+
+ // considering near trees and producers
+ prio += (30 - bf->trees_nearby_) * 2 +
+ bf->producers_nearby_.at(bo.production_hint_) * 5 -
+ new_buildings_stop_ * 15;
+
+ // considering space consumers nearby
+ prio -= bf->space_consumers_nearby_ * 5;
+
+ } else if (!new_buildings_stop_) { // gamekeepers or so
+ if (bo.stocklevel_time < game().get_gametime() - 5 * 1000) {
+ bo.stocklevel_ =
+ get_stocklevel_by_hint(static_cast<size_t>(bo.production_hint_));
+ bo.stocklevel_time = game().get_gametime();
+ }
+
+ if (bo.stocklevel_ > 50)
+ continue;
// especially for fish breeders
- if (bo.need_water_)
- prio = bf->water_nearby_;
-
- if (bo.total_count() == 0)
- prio += 5;
-
- if (bo.total_count() < bo.cnt_target_) {
- prio += bf->producers_nearby_.at(bo.production_hint_) * 10;
- prio += recalc_with_border_range(*bf, prio);
-
- } else if (bo.stocklevel_ < 50 && !new_buildings_stop_) {
- prio += bf->producers_nearby_.at(bo.production_hint_) * 5;
- prio += recalc_with_border_range(*bf, prio); // only for not wood producers_
- } else
- continue;
+ if (bo.need_water_ && bf->water_nearby_ < 5)
+ continue;
+ prio = bf->water_nearby_;
+
+ if (bo.total_count() > bo.cnt_target_)
+ continue;
+
+ prio += bf->producers_nearby_.at(bo.production_hint_) * 10;
+ prio += recalc_with_border_range(*bf, prio);
}
if (prio <= 0)
continue;
- } else if (bo.recruitment_ && gametime >
- kBaseInfrastructureTime && !new_buildings_stop_) {
+ } else if (bo.recruitment_ && !new_buildings_stop_) {
// this will depend on number of mines_ and productionsites
if (static_cast<int32_t>((productionsites.size() + mines_.size()) / 30) >
- bo.total_count() && bo.cnt_under_construction_ ==
- 0)
+ bo.total_count() &&
+ bo.cnt_under_construction_ == 0)
prio = 4 + bulgarian_constant;
} else { // finally normal productionsites
if (bo.production_hint_ >= 0)
@@ -1103,102 +1165,59 @@
if ((bo.cnt_under_construction_ + bo.unoccupied_) > 0)
continue;
- // if hunter and too little critters nearby skipping
- if (bo.is_hunter_ && bf->critters_nearby_ < 5)
- continue;
- // similarly for fishers
- if (bo.need_water_ && bf->fish_nearby_ <= 1)
- continue;
-
- // first eliminate buildings needing water if there is short supplies
- if (bo.need_water_ && bf->water_nearby_ < 4)
- continue;
-
- if (bo.is_basic_ && bo.total_count() == 0)
+ if (bo.forced_after_ < gametime && bo.total_count() == 0) {
prio = 150 + max_preciousness;
- else if (bo.is_food_basic_ && game().get_gametime() >
- kPrimaryFoodStartTime && bo.total_count() ==
- 0) {
- prio = 40 + max_preciousness;
- } else if (game().get_gametime() <
- kBaseInfrastructureTime ||
- new_buildings_stop_) // leave 15 minutes for basic infrastructure only
- continue;
- else if ((bo.is_basic_ && bo.total_count() <=
- 1) || (output_is_needed && bo.total_count() == 0))
- prio = 80 + max_preciousness;
+ } else if (new_buildings_stop_)
+ continue;
+ else if (bo.desc->enhancement() != INVALID_INDEX)
+ ; // just go on
+ else if (!output_is_needed)
+ continue;
+ else
+ prio = 0;
+
+ if (bo.cnt_built_ ==
+ 1 && game().get_gametime() > 40 * 60 * 1000 && bo.desc->enhancement() !=
+ INVALID_INDEX && !mines_.empty()) {
+ prio += max_preciousness + bulgarian_constant;
+ // printf (" proposing %20s as a second upgradable building\n",bo.name);
+ } else if (!output_is_needed)
+ continue;
else if (bo.inputs_.size() == 0) {
- bo.cnt_target_ =
- 1 + static_cast<int32_t>(mines_.size() + productionsites.size()) / 8;
-
- if (bo.cnt_built_ >
- bo.cnt_target_ &&
- !(bo.space_consumer_ || bo.is_food_basic_)) // spaceconsumers_ and basic_s
- // can be built more then target
- continue;
-
- if (bo.stocklevel_time < game().get_gametime() - 5 * 1000) {
- bo.stocklevel_ = get_stocklevel(bo);
- bo.stocklevel_time = game().get_gametime();
- }
-
- if (bo.stocklevel_ < 50) {
- prio = max_preciousness + bulgarian_constant;
-
- if (bo.space_consumer_) // need to consider trees nearby
- prio += 20 - (bf->trees_nearby_ / 3);
-
- if (!bo.space_consumer_)
- prio -= bf->producers_nearby_.at(bo.outputs_.at(0)) *
- 20; // leave some free space between them
-
- if (bo.cnt_built_ < 2)
- prio += 5;
-
- prio = recalc_with_border_range(*bf, prio);
-
- if (bo.stocklevel_ < 20)
- prio += 20 - bo.stocklevel_;
-
- // fisher
- if (bo.need_water_) {
- prio += bf->fish_nearby_ - 4;
- }
-
- // hunters
- if (bo.is_hunter_) {
- prio += (bf->critters_nearby_ * 2) - 8;
- }
-
- }
+
+ prio += max_needed_preciousness + bulgarian_constant;
+
+ if (bo.space_consumer_) // need to consider trees nearby
+ prio += 20 - (bf->trees_nearby_ / 3);
+
+ // we attempt to cluster space consumers together
+ if (bo.space_consumer_) // need to consider trees nearby
+ prio += bf->space_consumers_nearby_ * 2;
+
+ if (bo.space_consumer_ && !bf->water_nearby_) // not close to water
+ prio += 1;
+
+ if (bo.space_consumer_ &&
+ !bf->unowned_mines_pots_nearby_) // not close to mountains
+ prio += 1;
+
+ if (!bo.space_consumer_)
+ prio -= bf->producers_nearby_.at(bo.outputs_.at(0)) *
+ 20; // leave some free space between them
+
+ prio -= bf->space_consumers_nearby_ * 3;
+
} else if (!bo.inputs_.empty()) {
- // to have two buildings from everything (intended for upgradeable buildings)
- // but I do not know how to identify such buildings
- if (bo.cnt_built_ == 1
- && game().get_gametime() > 60 * 60 * 1000
- && bo.desc->enhancement() != INVALID_INDEX
- && !mines_.empty())
- {
- prio = max_preciousness + bulgarian_constant;
- }
- // if output is needed and there are no idle buildings
- else if (output_is_needed) {
- if (bo.cnt_built_ > 0 && bo.current_stats_ > 80) {
- prio = max_preciousness + bulgarian_constant + 30;
-
- } else if (bo.cnt_built_ > 0 && bo.current_stats_ > 55) {
- prio = max_preciousness + bulgarian_constant;
-
- }
+ if (bo.total_count() == 0)
+ prio += max_needed_preciousness + bulgarian_constant;
+ if (bo.cnt_built_ > 0 && bo.current_stats_ > 70) {
+ prio = max_needed_preciousness + bulgarian_constant;
}
}
if (prio <= 0)
continue;
- // then we consider borders and enemies nearby (if any)
- prio = recalc_with_border_range(*bf, prio);
-
//+1 if any consumers_ are nearby
consumers_nearby_count = 0;
@@ -1211,33 +1230,36 @@
} // production sites done
else if (bo.type == BuildingObserver::MILITARYSITE) {
- if (new_military_buildings_stop && !bf->enemy_nearby_)
- continue;
-
- if (near_enemy_b_buildings_stop && bf->enemy_nearby_)
+ if (expansion_mode == kNoNewMilitary)
+ continue;
+
+ if (expansion_mode == kDefenseOnly && !bf->enemy_nearby_)
+ continue;
+
+ if (expansion_mode ==
+ kResourcesOrDefense &&
+ !(bf->enemy_nearby_ || bf->unowned_mines_pots_nearby_ || bf->stones_nearby_))
continue;
if (bf->enemy_nearby_ && bo.fighting_type_)
; // it is ok, go on
- else if (bf->unowned_mines_pots_nearby_ >
- 0 && (bo.mountain_conqueror_ || bo.expansion_type_))
+ else if (bf->unowned_mines_pots_nearby_ > 2 &&
+ (bo.mountain_conqueror_ || bo.expansion_type_))
; // it is ok, go on
- else if (bf->unowned_land_nearby_ && bo.expansion_type_) {
- // decreasing probability for big buidlings
- if (bo.desc->get_size() == 2 && gametime % 5 >= 1)
+ else if (bf->unowned_land_nearby_ &&
+ bo.expansion_type_ && num_milit_constructionsites <= 1) {
+ ; // we allow big buildings now
+ } else if (bf->unowned_land_nearby_ &&
+ bo.expansion_type_) { // decreasing probability for big buidlings
+ if (bo.desc->get_size() == 2 && gametime % 15 >= 1)
continue;
- if (bo.desc->get_size() == 3 && gametime % 15 >= 1)
+ if (bo.desc->get_size() == 3 && gametime % 40 >= 1)
continue;
}
// it is ok, go on
else
continue; // the building is not suitable for situation
- if (bo.desc->get_size() ==
- 3 && game().get_gametime() <
- 15 * 60 * 1000) // do not built fortresses in first half of hour of game
- continue;
-
if (!bf->unowned_land_nearby_)
continue;
@@ -1254,8 +1276,15 @@
mines_spots_score += 8;
}
+ // a boost to prevent an expansion halt
+ int32_t local_boost = 0;
+ if (num_milit_constructionsites == 1)
+ local_boost = 50;
+ if (num_milit_constructionsites == 0)
+ local_boost = 200;
+
prio = (bf->unowned_land_nearby_ - 4 + mines_spots_score + bf->stones_nearby_ / 2 +
- bf->military_loneliness_ / 5 - 100 + military_boost); // * (1 + type);
+ bf->military_loneliness_ / 5 - 100 + local_boost); // * (1 + type);
if (bo.desc->get_size() < maxsize)
prio = prio - 5; // penalty
@@ -1274,10 +1303,10 @@
// Militarysites are slightly important as well, to have a bigger
// chance for a warehouses (containing waiting soldiers or wares
// needed for soldier training) near the frontier.
- if ((static_cast<int32_t>(productionsites.size() + mines_.size())) / 35 >
- static_cast<int32_t>(numof_warehouses_) && bo.cnt_under_construction_ ==
- 0)
- prio = 13;
+ if ((static_cast<int32_t>(productionsites.size() + mines_.size()) + 20) / 35 >
+ static_cast<int32_t>(numof_warehouses_) &&
+ bo.cnt_under_construction_ == 0)
+ prio = 20;
// take care about borders and enemies
prio = recalc_with_border_range(*bf, prio);
@@ -1292,10 +1321,9 @@
continue;
// build after 20 production sites and then after each 50 production site
- if (static_cast<int32_t>((productionsites.size() + 30) / 50) >
- bo.total_count() && bo.cnt_under_construction_ ==
- 0)
- prio = 4;
+ if (static_cast<int32_t>((productionsites.size() + 30) / 50) > bo.total_count() &&
+ bo.cnt_under_construction_ == 0)
+ prio = 4 + bulgarian_constant;
// take care about borders and enemies
prio = recalc_with_border_range(*bf, prio);
@@ -1332,13 +1360,13 @@
for (uint32_t i = 0; i < buildings_.size() && productionsites.size() > 8; ++i) {
BuildingObserver& bo = buildings_.at(i);
- if (!bo.mines_marble_ && gametime <
- kBaseInfrastructureTime) // allow only stone mines_ in early stages of game
- continue;
-
if (!bo.buildable(*player_) || bo.type != BuildingObserver::MINE)
continue;
+ if (bo.prohibited_till_ > gametime) {
+ continue;
+ }
+
if (gametime - bo.construction_decision_time_ < kBuildingMinInterval)
continue;
@@ -1354,20 +1382,19 @@
bo.stocklevel_time = game().get_gametime();
}
- // Only try to build mines_ that produce needed wares.
- if (((bo.cnt_built_ - bo.unoccupied_) > 0 && bo.current_stats_ < 20) || bo.stocklevel_ >
- 40 + static_cast<uint32_t>(bo.mines_marble_) * 30) {
+ // if we have enough mined resources, do not consider a mine here
+ if (bo.stocklevel_ > 100)
+ continue;
+ // if current ones are performing badly
+ if (bo.total_count() >= 2 && bo.current_stats_ < 50)
continue;
- }
// this is penalty if there are existing mines too close
// it is treated as multiplicator for count of near mines
uint32_t nearness_penalty = 0;
if ((bo.cnt_built_ + bo.cnt_under_construction_) == 0)
nearness_penalty = 0;
- else if (bo.mines_marble_)
- nearness_penalty = 7;
else
nearness_penalty = 10;
@@ -1410,7 +1437,6 @@
proposed_priority = prio;
proposed_coords = (*j)->coords;
mine = true;
-
}
} // end of evaluation of field
}
@@ -1419,7 +1445,6 @@
} // end of mines_ section
// if there is no winner:
- // if (proposed_building == INVALID_INDEX) {
if (best_building == nullptr) {
mine = false;
@@ -1432,14 +1457,26 @@
game().map().get_fcoords(proposed_coords), game().get_gametime() + 120000); // two minutes
blocked_fields.push_back(blocked);
- // if space consumer we block also nearby fields
- if (best_building->space_consumer_ && !best_building->plants_trees_) {
+ // we block also nearby fields
+ // if farms and so on, for quite a long time
+ // if military sites only for short time for AI can update information on near buildable fields
+ if ((best_building->space_consumer_ && !best_building->plants_trees_) || best_building->type ==
+ BuildingObserver::MILITARYSITE) {
+ uint32_t block_time = 0;
+ uint32_t block_area = 0;
+ if (best_building->space_consumer_) {
+ block_time = 45 * 60 * 1000;
+ block_area = 3;
+ } else { // militray buildings for a very short time
+ block_time = 25 * 1000;
+ block_area = 6;
+ }
Map& map = game().map();
- MapRegion<Area<FCoords>> mr(map, Area<FCoords>(map.get_fcoords(proposed_coords), 3));
+ MapRegion<Area<FCoords>> mr(map, Area<FCoords>(map.get_fcoords(proposed_coords), block_area));
do {
BlockedField blocked2(
- map.get_fcoords(*(mr.location().field)), game().get_gametime() + 45 * 60 * 1000);
+ map.get_fcoords(*(mr.location().field)), game().get_gametime() + block_time);
blocked_fields.push_back(blocked2);
} while (mr.advance(map));
}
@@ -1540,8 +1577,8 @@
// Remove flags of dead end roads, as long as no more wares are stored on them
for (EconomyObserver* eco_obs : economies) {
for (std::list<Flag const*>::iterator flag_iter = eco_obs->flags.begin();
- flag_iter != eco_obs->flags.end();
- ++flag_iter) {
+ flag_iter != eco_obs->flags.end();
+ ++flag_iter) {
if ((*flag_iter)->is_dead_end() && (*flag_iter)->current_wares() == 0) {
game().send_player_bulldoze(*const_cast<Flag*>(*flag_iter));
flag_iter = eco_obs->flags.erase(flag_iter);
@@ -1551,9 +1588,8 @@
}
// force a split on roads that are longer than 3 parts
- // actually we do not care for loss of building capabilities - normal maps
- // should have enough space and the computer can expand it's territory.
- if (!roads.empty()) {
+ // with exemption when there is too few building spots
+ if (spots_ > 20 && !roads.empty()) {
const Path& path = roads.front()->get_path();
if (path.get_nsteps() > 3) {
@@ -1600,12 +1636,8 @@
if (economies.size() > 1)
finish = connect_flag_to_another_economy(flag);
- // try to improve the roads at this flag
- // TODO(unknown): do this only on useful places - the attempt below
- // unfortunatey did not work as it should...
- // if the flag is full of wares or if it is not yet a fork.
- if (!finish) //&& (!flag.has_capacity() || flag.nr_of_roads() < 3))
- finish = improve_transportation_ways(flag);
+ if (!finish)
+ finish = improve_transportation_ways(flag, !flag.has_capacity());
// cycle through flags one at a time
eco->flags.push_back(eco->flags.front());
@@ -1631,7 +1663,7 @@
functor.economy = flag.get_economy();
Map& map = game().map();
map.find_reachable_fields(
- Area<FCoords>(map.get_fcoords(flag.get_position()), 16), &reachable, check, functor);
+ Area<FCoords>(map.get_fcoords(flag.get_position()), 20), &reachable, check, functor);
if (reachable.empty())
return false;
@@ -1672,11 +1704,12 @@
}
// adds alternative ways to already existing ones
-bool DefaultAI::improve_transportation_ways(const Flag& flag) {
+// ('shortcuts' if a road can be shortened significantly)
+bool DefaultAI::improve_transportation_ways(const Flag& flag, const bool force) {
// First of all try to remove old building flags to clean up the road web if possible
for (std::list<Widelands::Coords>::iterator coords_iter = flags_to_be_removed.begin();
- coords_iter != flags_to_be_removed.end();
- ++coords_iter) {
+ coords_iter != flags_to_be_removed.end();
+ ++coords_iter) {
// Maybe the flag was already removed?
FCoords f = game().map().get_fcoords(*(coords_iter));
@@ -1696,6 +1729,28 @@
std::vector<NearFlag> nearflags;
queue.push(NearFlag(flag, 0, 0));
Map& map = game().map();
+ // shortcut is made (attempted) if (current_road - possible_shortcut)>minred
+ uint16_t minred = 20;
+ // with exemption of forced road
+ if (force)
+ minred = -10;
+ // when testing flags do not go farer from starting flag then:
+ uint16_t checkradius = 12;
+ // with only one exemption, when the flag is on the end of road
+ // presuming there is a building attached to it)
+ // so we count number of roads attached to starting flag
+ uint16_t roadscount = 0;
+ for (uint8_t i = 1; i <= 6; ++i) {
+ Road* const road = flag.get_road(i);
+ if (road)
+ roadscount += 1;
+ }
+ if (roadscount == 1) {
+ checkradius = 20;
+ }
+ // do not try to connect if too many roads going from flag)
+ if (roadscount >= 4 && !force)
+ return false;
while (!queue.empty()) {
std::vector<NearFlag>::iterator f =
@@ -1723,26 +1778,33 @@
int32_t dist = map.calc_distance(flag.get_position(), endflag->get_position());
- if (dist > 12) // out of range
+ if (dist > checkradius) // out of range
continue;
queue.push(NearFlag(*endflag, nf.cost_ + road->get_path().get_nsteps(), dist));
}
}
- std::sort(nearflags.begin(), nearflags.end(), CompareDistance());
+ // usually we create consider shortest shortcut, but sometimes
+ // we seek biggest reduction
+ std::sort(nearflags.begin(), nearflags.end(), CompareShortening());
+
CheckStepRoadAI check(player_, MOVECAPS_WALK, false);
- for (uint32_t i = 1; i < nearflags.size(); ++i) {
+ // testing only first 10 nearfields that meet the condition
+ for (uint32_t i = 1; i < nearflags.size() && i < 10; ++i) {
NearFlag& nf = nearflags.at(i);
- if (2 * nf.distance_ + 2 < nf.cost_) {
+ // testing the nearflag
+ if ((nf.cost_ - nf.distance_) > minred) {
+
Path& path = *new Path();
- if (map.findpath(flag.get_position(), nf.flag->get_position(), 0, path, check) >=
- 0 && static_cast<int32_t>(2 * path.get_nsteps() + 2) < nf.cost_) {
- game().send_player_build_road(player_number(), path);
- return true;
+ if (map.findpath(flag.get_position(), nf.flag->get_position(), 0, path, check) >= 0) {
+ if (static_cast<int32_t>(nf.cost_ - path.get_nsteps()) > minred) {
+ game().send_player_build_road(player_number(), path);
+ return true;
+ }
}
delete &path;
@@ -1766,8 +1828,8 @@
}
for (std::list<EconomyObserver*>::iterator obs_iter = economies.begin();
- obs_iter != economies.end();
- ++obs_iter) {
+ obs_iter != economies.end();
+ ++obs_iter) {
// check if any flag has changed its economy
std::list<Flag const*>& fl = (*obs_iter)->flags;
@@ -1815,10 +1877,15 @@
site.unoccupied_till_ = game().get_gametime();
}
+ // do not dismantle or upgrade the same type of building too soon - to give some time to update
+ // statistics
+ if (site.bo->last_dismantle_time_ > game().get_gametime() - 30 * 1000)
+ return false;
+
// Get max radius of recursive workarea
Workarea_Info::size_type radius = 0;
const Workarea_Info& workarea_info = site.bo->desc->m_workarea_info;
- for (const std::pair<uint32_t, std::set<std::string> > & temp_info : workarea_info) {
+ for (const std::pair<uint32_t, std::set<std::string>>& temp_info : workarea_info) {
if (radius < temp_info.first) {
radius = temp_info.first;
}
@@ -1826,10 +1893,62 @@
Map& map = game().map();
- // do not dismantle same type of building too soon - to give some time to update statistics
- // yes it interferes with building updates, but not big problem here
- if (site.bo->last_dismantle_time_ > game().get_gametime() - 30 * 1000)
- return false;
+ // first we try to upgrade
+ // Upgrading policy
+ // a) if there are two buildings and none enhanced and there are workers
+ // available, one is to be enhanced
+ // b) if there are two buildings
+ // statistics percents are decisive
+ const Building_Index enhancement = site.site->descr().enhancement();
+ if (enhancement != INVALID_INDEX && (site.bo->cnt_built_ - site.bo->unoccupied_) > 1) {
+
+ Building_Index enbld = INVALID_INDEX; // to get rid of this
+ BuildingObserver* bestbld = nullptr;
+
+ // Only enhance buildings that are allowed (scenario mode)
+ // do not do decisions to fast
+ if (player_->is_building_type_allowed(enhancement)) {
+
+ const BuildingDescr& bld = *tribe_->get_building_descr(enhancement);
+ BuildingObserver& en_bo = get_building_observer(bld.name().c_str());
+
+ if (gametime - en_bo.construction_decision_time_ >=
+ kBuildingMinInterval && (en_bo.cnt_under_construction_ + en_bo.unoccupied_) ==
+ 0) {
+
+ // don't upgrade without workers
+ if (site.site->has_workers(enhancement, game())) {
+
+ // forcing first upgrade
+ if (en_bo.cnt_built_ == 0 && !mines_.empty()) {
+ enbld = enhancement;
+ bestbld = &en_bo;
+ }
+
+ // if the decision was not made yet, consider normal upgrade
+ if (enbld == INVALID_INDEX) {
+ // compare the performance %
+ if (static_cast<int32_t>(en_bo.current_stats_) -
+ static_cast<int32_t>(site.bo->current_stats_) >
+ 20) {
+
+ enbld = enhancement;
+ bestbld = &en_bo;
+ }
+ }
+ }
+ }
+
+ // Enhance if enhanced building is useful
+ // additional: we dont want to lose the old building
+ if (enbld != INVALID_INDEX) {
+ game().send_player_enhance_building(*site.site, enbld);
+ bestbld->construction_decision_time_ = gametime;
+
+ return true;
+ }
+ }
+ }
// Lumberjack / Woodcutter handling
if (site.bo->need_trees_) {
@@ -1865,9 +1984,8 @@
// Wells handling
if (site.bo->mines_water_) {
- if (site.unoccupied_till_ + 6 * 60 * 1000 < game().get_gametime()
- && site.site->get_statistics_percent() ==
- 0) {
+ if (site.unoccupied_till_ + 6 * 60 * 1000 < game().get_gametime() &&
+ site.site->get_statistics_percent() == 0) {
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);
@@ -1883,6 +2001,7 @@
if (map.find_immovables(
Area<FCoords>(map.get_fcoords(site.site->get_position()), radius),
nullptr,
+
FindImmovableAttribute(MapObjectDescr::get_attribute_id("granite"))) == 0) {
// destruct the building and it's flag (via flag destruction)
// the destruction of the flag avoids that defaultAI will have too many
@@ -1892,9 +2011,8 @@
return true;
}
- if (site.unoccupied_till_ + 6 * 60 * 1000 < game().get_gametime()
- && site.site->get_statistics_percent() ==
- 0) {
+ if (site.unoccupied_till_ + 6 * 60 * 1000 < game().get_gametime() &&
+ site.site->get_statistics_percent() == 0) {
// it is possible that there are stones but quary is not able to mine them
site.bo->last_dismantle_time_ = game().get_gametime();
flags_to_be_removed.push_back(site.site->base_flag().get_position());
@@ -1908,13 +2026,14 @@
// All other SPACE_CONSUMERS without input and above target_count
if (site.bo->inputs_.empty() // does not consume anything
- && site.bo->production_hint_ ==
- -1 // not a renewing building (forester...)
- && site.unoccupied_till_ +
- 10 * 60 * 1000 <
- game().get_gametime() // > 10 minutes old
- && site.site->can_start_working() // building is occupied
- && site.bo->space_consumer_ && !site.bo->plants_trees_) {
+ &&
+ site.bo->production_hint_ == -1 // not a renewing building (forester...)
+ &&
+ site.unoccupied_till_ + 10 * 60 * 1000 < game().get_gametime() // > 10 minutes old
+ &&
+ site.site->can_start_working() // building is occupied
+ &&
+ site.bo->space_consumer_ && !site.bo->plants_trees_) {
// if we have more buildings then target
if (site.bo->cnt_built_ > site.bo->cnt_target_) {
@@ -1923,8 +2042,8 @@
site.bo->stocklevel_time = game().get_gametime();
}
- if (site.site->get_statistics_percent()<
- 30 && site.bo->stocklevel_> 100) { // production stats == 0%
+ if (site.site->get_statistics_percent() < 30 &&
+ site.bo->stocklevel_ > 100) { // production stats == 0%
site.bo->last_dismantle_time_ = game().get_gametime();
flags_to_be_removed.push_back(site.site->base_flag().get_position());
game().send_player_dismantle(*site.site);
@@ -1932,8 +2051,8 @@
}
}
- // regardless of count of sites a building can be dismanteld if it performs too bad
- if (site.site->get_statistics_percent() <= 10) {
+ // a building can be dismanteld if it performs too bad, if it is not the last one
+ if (site.site->get_statistics_percent() <= 10 && site.bo->total_count() > 1) {
flags_to_be_removed.push_back(site.site->base_flag().get_position());
game().send_player_dismantle(*site.site);
@@ -1944,12 +2063,11 @@
}
// buildings with inputs_, checking if we can a dismantle some due to low performance
- if (!site.bo->inputs_.empty() && (site.bo->cnt_built_ - site.bo->unoccupied_) >=
- 3 && site.site->can_start_working() && site.site->get_statistics_percent() <
- 20 && // statistics for the building
- site.bo->current_stats_<30 && // overall statistics
- (game().get_gametime() - site.unoccupied_till_)> 10 *
- 60 * 1000) {
+ if (!site.bo->inputs_.empty() && (site.bo->cnt_built_ - site.bo->unoccupied_) >= 3 &&
+ site.site->can_start_working() &&
+ site.site->get_statistics_percent() < 20 && // statistics for the building
+ site.bo->current_stats_ < 30 && // overall statistics
+ (game().get_gametime() - site.unoccupied_till_) > 10 * 60 * 1000) {
site.bo->last_dismantle_time_ = game().get_gametime();
flags_to_be_removed.push_back(site.site->base_flag().get_position());
@@ -1959,13 +2077,11 @@
// remaining buildings without inputs and not supporting ones (fishers only left probably and
// huters)
- // first if is only for log, second one is "executive"
- if (site.bo->inputs_.size() ==
- 0 && site.bo->production_hint_ <
- 0 && site.site->can_start_working()
- && !site.bo->space_consumer_ && site.site->get_statistics_percent() <
- 10 && ((game().get_gametime() - site.built_time_) > 10 * 60 * 1000)) {
+ if (site.bo->inputs_.size() == 0 && site.bo->production_hint_ < 0 &&
+ site.site->can_start_working() && !site.bo->space_consumer_ &&
+ site.site->get_statistics_percent() < 10 &&
+ ((game().get_gametime() - site.built_time_) > 10 * 60 * 1000)) {
site.bo->last_dismantle_time_ = game().get_gametime();
flags_to_be_removed.push_back(site.site->base_flag().get_position());
@@ -1984,7 +2100,6 @@
uint16_t score = site.bo->stocklevel_;
-
if (score > 150 && site.bo->cnt_built_ > site.bo->cnt_target_) {
site.bo->last_dismantle_time_ = game().get_gametime();
@@ -2004,73 +2119,6 @@
}
}
- // Upgrading policy
- // a) if there are two buildings and none enhanced, one is enhanced
- // b) if there are two buildings and at least one functional
- // statistics percents are decisive
-
- // do not upgrade if current building is only one in operation
- if ((site.bo->cnt_built_ - site.bo->unoccupied_) <= 1)
- return false;
-
- // Check whether building is enhanceable and if wares of the enhanced
- // buildings are needed. If yes consider an upgrade.
- const Building_Index enhancement = site.site->descr().enhancement();
- Building_Index enbld = INVALID_INDEX; // to get rid of this
- BuildingObserver* bestbld = nullptr;
-
- // Only enhance buildings that are allowed (scenario mode)
- if (player_->is_building_type_allowed(enhancement)) {
- const BuildingDescr& bld = *tribe_->get_building_descr(enhancement);
- BuildingObserver& en_bo = get_building_observer(bld.name().c_str());
-
- // do not build the same building so soon (kind of duplicity check)
- if (gametime - en_bo.construction_decision_time_ >= kBuildingMinInterval)
- {
- // Don't enhance this building, if there is already one of same type
- // under construction or unoccupied_
- if (en_bo.cnt_under_construction_ + en_bo.unoccupied_ <= 0)
- {
- // don't upgrade without workers
- if (site.site->has_workers(enhancement, game()))
- {
- // forcing first upgrade
- if ((en_bo.cnt_under_construction_ + en_bo.cnt_built_ + en_bo.unoccupied_) == 0
- && (site.bo->cnt_built_ - site.bo->unoccupied_) >= 1
- && (game().get_gametime() - site.unoccupied_till_) > 30 * 60 * 1000
- && !mines_.empty())
- {
- game().send_player_enhance_building(*site.site, enhancement);
- return true;
- }
- }
- }
- }
-
- // now, let consider normal upgrade
- // do not upgrade if candidate production % is too low
- if ((en_bo.cnt_built_ - en_bo.unoccupied_) != 0
- || (en_bo.cnt_under_construction_ + en_bo.unoccupied_) <= 0
- || en_bo.current_stats_ >= 50) {
-
- if (en_bo.current_stats_ > 65
- && ((en_bo.current_stats_ - site.bo->current_stats_) + // priority for enhancement
- (en_bo.current_stats_ - 65)) > 0)
- {
- enbld = enhancement;
- bestbld = &en_bo;
- }
- }
- }
-
- // Enhance if enhanced building is useful
- // additional: we dont want to lose the old building
- if (enbld != INVALID_INDEX) {
- game().send_player_enhance_building(*site.site, enbld);
- bestbld->construction_decision_time_ = gametime;
- changed = true;
- }
-
return changed;
}
@@ -2102,18 +2150,53 @@
return true;
}
+ // dont check the performance too soon
+ if (site.built_time_ + 5 * 60 * 1000 > gametime)
+ return false;
+
// It takes some time till performance gets to 0
// so I use 40% as a limit to check if there are some resources left
if (site.site->get_statistics_percent() > 40)
return false;
- // Check if mine ran out of resources
- uint8_t current = field->get_resources_amount();
-
- if (current < 1) {
- // destruct the building and it's flag (via flag destruction)
- // the destruction of the flag avoids that defaultAI will have too many
- // unused roads - if needed the road will be rebuild directly.
+ // Check if mine stil can mine resources
+ uint32_t starting_resources = 0;
+ uint32_t remaining_resources = 0;
+ const uint8_t mined_resource = field->get_resources();
+
+ MapRegion<Area<FCoords>> mr(map, Area<FCoords>(map.get_fcoords(site.site->get_position()), 6));
+ do {
+ uint8_t fres = mr.location().field->get_resources();
+ uint32_t amount = mr.location().field->get_resources_amount();
+ uint32_t start_amount = mr.location().field->get_starting_res_amount();
+
+ if (fres != mined_resource) {
+ amount = 0;
+ start_amount = 0;
+ }
+
+ remaining_resources += amount;
+ starting_resources += start_amount;
+ } while (mr.advance(map));
+
+ bool mine_can_mine = true;
+ if (((starting_resources - remaining_resources) * 100 / starting_resources) + 4 >
+ site.bo->mines_percent_) {
+ mine_can_mine = false;
+ }
+
+ // if mine can mine - probably food is missing
+ if (mine_can_mine)
+ return false;
+
+ if (site.bo->stocklevel_time < game().get_gametime() - 5 * 1000) {
+ site.bo->stocklevel_ = get_stocklevel_by_hint(site.bo->production_hint_);
+ site.bo->stocklevel_time = game().get_gametime();
+ }
+
+ // if mine can not mine anymore, but we have enough stock
+ if (!mine_can_mine && site.bo->stocklevel_ > 100) {
+ // dismantle mine
flags_to_be_removed.push_back(site.site->base_flag().get_position());
game().send_player_dismantle(*site.site);
@@ -2122,44 +2205,40 @@
// Check whether building is enhanceable. If yes consider an upgrade.
const Building_Index enhancement = site.site->descr().enhancement();
- Building_Index enbld = INVALID_INDEX;
- BuildingObserver* bestbld = nullptr;
+
+ // if no enhancement is possible
+ if (enhancement == INVALID_INDEX) {
+ flags_to_be_removed.push_back(site.site->base_flag().get_position());
+ game().send_player_dismantle(*site.site);
+ site.bo->construction_decision_time_ = gametime;
+ return false;
+ }
+
+ // Building_Index enbld = INVALID_INDEX;
+ // BuildingObserver* bestbld = nullptr;
bool changed = false;
- // Only enhance buildings that are allowed (scenario mode)
if (player_->is_building_type_allowed(enhancement)) {
// first exclude possibility there are enhancements in construction or unoccupied_
const BuildingDescr& bld = *tribe_->get_building_descr(enhancement);
BuildingObserver& en_bo = get_building_observer(bld.name().c_str());
- if (en_bo.unoccupied_ + en_bo.cnt_under_construction_ <= 0)
- {
- // do not upgrade target building are not working properly (probably do not have food)
- if (en_bo.cnt_built_ <= 0 && en_bo.current_stats_ >= 60)
- {
- // do not build the same building so soon (kind of duplicity check)
- if (gametime - en_bo.construction_decision_time_ >= kBuildingMinInterval)
- {
- // Check if mine needs an enhancement to mine more resources
- uint8_t const until =
- field->get_starting_res_amount() * (100 - site.bo->mines_percent_) / 100;
+ // if it is too soon for enhancement and making sure there are no unoccupied mines
+ if (gametime - en_bo.construction_decision_time_ >= kBuildingMinInterval &&
+ en_bo.unoccupied_ + en_bo.cnt_under_construction_ == 0) {
- if (until >= current) {
- enbld = enhancement;
- bestbld = &en_bo;
- }
- }
+ // now verify that there are enough workers
+ if (site.site->has_workers(enhancement, game())) { // enhancing
+ game().send_player_enhance_building(*site.site, enhancement);
+ en_bo.construction_decision_time_ = gametime;
+ changed = true;
+ } else if (gametime % 40 == 0) { // dismantling with low probability
+ flags_to_be_removed.push_back(site.site->base_flag().get_position());
+ game().send_player_dismantle(*site.site);
+ site.bo->construction_decision_time_ = gametime;
}
}
}
- // Enhance if enhanced building is useful and possible
- if (enbld != INVALID_INDEX) {
- game().send_player_enhance_building(*site.site, enbld);
- bestbld->construction_decision_time_ = gametime;
- changed = true;
-
- }
-
return changed;
}
@@ -2222,16 +2301,6 @@
if (it->site->stationedSoldiers().size() == 0)
unstationed_milit_buildings_ += 1;
- // count militarysites in construction
- military_under_constr_ = 0;
-
- for (uint32_t j = 0; j < buildings_.size(); ++j) {
- BuildingObserver& bo = buildings_.at(j);
-
- if (bo.type == BuildingObserver::MILITARYSITE)
- military_under_constr_ += bo.cnt_under_construction_;
- }
-
// Only useable, if defaultAI owns at least one militarysite
if (militarysites.empty())
return false;
@@ -2242,13 +2311,11 @@
MilitarySite* ms = militarysites.front().site;
uint32_t const vision = ms->descr().vision_range();
FCoords f = map.get_fcoords(ms->get_position());
- // look if there is any enemy land nearby
- // FindNodeEnemy find_enemy(player, game());
- // look if there is any enemies building
+ // look if there are any enemies building
FindNodeEnemiesBuilding find_enemy(player_, game());
// first if there are enemies nearby, check for buildings not land
- if (map.find_fields(Area<FCoords>(f, vision + 2), nullptr, find_enemy) == 0) {
+ if (map.find_fields(Area<FCoords>(f, vision + 4), nullptr, find_enemy) == 0) {
// If no enemy in sight - decrease the number of stationed soldiers
// as long as it is > 1 - BUT take care that there is a warehouse in the
// same economy where the thrown out soldiers can go to.
@@ -2269,9 +2336,14 @@
update_buildable_field(bf, vision, true);
const int32_t size_penalty = ms->get_size() - 1;
- if (bf.military_capacity_ > 9 && bf.military_presence_ >
- 3 && bf.military_loneliness_<160 && bf.military_stationed_>(2 + size_penalty)) {
+ int16_t score = 0; // <<=========
+ score += (bf.military_capacity_ > 9);
+ score += (bf.military_presence_ > 3);
+ score += (bf.military_loneliness_ < 160);
+ score += (bf.military_stationed_ > (2 + size_penalty));
+ score += 2 * (bf.unowned_land_nearby_ < 10);
+ if (score >= 5) {
if (ms->get_playercaps() & Widelands::Building::PCap_Dismantle) {
flags_to_be_removed.push_back(ms->base_flag().get_position());
game().send_player_dismantle(*ms);
@@ -2289,14 +2361,16 @@
uint32_t const j = ms->maxSoldierCapacity();
uint32_t const k = ms->soldierCapacity();
- if (j > k)
- // game().send_player_change_soldier_capacity(*ms, j - k);
-
- if (MilitarySite::kPrefersHeroes != ms->get_soldier_preference())
- game().send_player_militarysite_set_soldier_preference(
- *ms, MilitarySite::kPrefersHeroes);
-
- changed = true;
+ if (j > k) {
+ game().send_player_change_soldier_capacity(*ms, j - k);
+ changed = true;
+ }
+
+ // and also set preference to Heroes
+ if (MilitarySite::kPrefersHeroes != ms->get_soldier_preference()) {
+ game().send_player_militarysite_set_soldier_preference(*ms, MilitarySite::kPrefersHeroes);
+ changed = true;
+ }
}
// reorder:;
@@ -2391,7 +2465,8 @@
void DefaultAI::consider_productionsite_influence(BuildableField& field,
Coords coords,
const BuildingObserver& bo) {
- if (bo.space_consumer_ && game().map().calc_distance(coords, field.coords) < 4)
+ if (bo.space_consumer_ && !bo.plants_trees_ &&
+ game().map().calc_distance(coords, field.coords) < 8)
++field.space_consumers_nearby_;
for (size_t i = 0; i < bo.inputs_.size(); ++i)
@@ -2440,8 +2515,8 @@
else if (upcast(Flag const, flag, &pi)) {
for (EconomyObserver* eco_obs : economies) {
for (std::list<Flag const*>::iterator flag_iter = eco_obs->flags.begin();
- flag_iter != eco_obs->flags.end();
- ++flag_iter) {
+ flag_iter != eco_obs->flags.end();
+ ++flag_iter) {
if (*flag_iter == flag) {
eco_obs->flags.erase(flag_iter);
return;
@@ -2449,8 +2524,8 @@
}
}
for (std::list<Flag const*>::iterator flag_iter = new_flags.begin();
- flag_iter != new_flags.end();
- ++flag_iter) {
+ flag_iter != new_flags.end();
+ ++flag_iter) {
if (*flag_iter == flag) {
new_flags.erase(flag_iter);
return;
@@ -2469,6 +2544,11 @@
get_building_observer(ref_cast<ConstructionSite, Building>(b).building().name().c_str());
++target_bo.cnt_under_construction_;
++num_constructionsites_;
+ if (target_bo.type == BuildingObserver::PRODUCTIONSITE)
+ ++num_prod_constructionsites;
+ if (target_bo.type == BuildingObserver::MILITARYSITE)
+ ++num_milit_constructionsites;
+
// Let defaultAI try to directly connect the constructionsite
next_road_due_ = game().get_gametime();
} else {
@@ -2504,6 +2584,7 @@
militarysites.back().bo = &bo;
militarysites.back().checks = bo.desc->get_size();
militarysites.back().enemies_nearby = true;
+
} else if (bo.type == BuildingObserver::WAREHOUSE)
++numof_warehouses_;
}
@@ -2518,6 +2599,11 @@
ref_cast<ConstructionSite const, Building const>(b).building().name().c_str());
--target_bo.cnt_under_construction_;
--num_constructionsites_;
+ if (target_bo.type == BuildingObserver::PRODUCTIONSITE)
+ --num_prod_constructionsites;
+ if (target_bo.type == BuildingObserver::MILITARYSITE)
+ --num_milit_constructionsites;
+
} else {
--bo.cnt_built_;
@@ -2550,6 +2636,7 @@
for (uint32_t i = 0; i < bo.inputs_.size(); ++i)
--wares.at(bo.inputs_.at(i)).consumers_;
} else if (bo.type == BuildingObserver::MILITARYSITE) {
+
for (std::list<MilitarySiteObserver>::iterator i = militarysites.begin();
i != militarysites.end();
++i)
@@ -2577,9 +2664,9 @@
for (const int16_t& temp_inputs : bo.inputs_) {
for (const BuildingObserver& temp_building : buildings_) {
if (temp_building.cnt_built_ &&
- std::find(temp_building.outputs_.begin(), temp_building.outputs_.end(), temp_inputs) !=
- temp_building.outputs_.end() &&
- check_supply(temp_building)) {
+ std::find(temp_building.outputs_.begin(), temp_building.outputs_.end(), temp_inputs) !=
+ temp_building.outputs_.end() &&
+ check_supply(temp_building)) {
++supplied;
break;
}
@@ -2640,7 +2727,6 @@
} else {
player_attackable[j - 1] = false;
}
-
}
if (!any_attackable) {
@@ -2781,3 +2867,28 @@
return false;
}
}
+
+// This is used for profiling, so usually this is not used :)
+void DefaultAI::print_land_stats() {
+ // this will just print statistics of land size
+ // intended for AI development only
+ uint32_t plr_in_game = 0;
+ uint32_t sum_l = 0;
+ uint32_t count_l = 0;
+ uint32_t sum_m = 0;
+ uint32_t count_m = 0;
+ Player_Number const nr_players = game().map().get_nrplayers();
+ iterate_players_existing_novar(p, nr_players, game())++ plr_in_game;
+ const Game::General_Stats_vector& genstats = game().get_general_statistics();
+ for (uint8_t j = 1; j <= plr_in_game; ++j) {
+ log(" player: %1d, landsize: %5d, military strength: %3d\n",
+ j,
+ genstats[j - 1].land_size.back(),
+ genstats[j - 1].miltary_strength.back());
+ sum_l += genstats[j - 1].land_size.back();
+ count_l += 1;
+ sum_m += genstats[j - 1].miltary_strength.back();
+ count_m += 1;
+ }
+ log(" Average: Landsize: %5d, military strenght: %3d\n", sum_l / count_l, sum_m / count_m);
+}
=== modified file 'src/ai/defaultai.h'
--- src/ai/defaultai.h 2014-07-26 10:43:23 +0000
+++ src/ai/defaultai.h 2014-07-29 20:53:33 +0000
@@ -127,7 +127,7 @@
bool construct_roads(int32_t);
bool improve_roads(int32_t);
- bool improve_transportation_ways(const Widelands::Flag&);
+ bool improve_transportation_ways(const Widelands::Flag&, bool force);
bool connect_flag_to_another_economy(const Widelands::Flag&);
bool check_economies();
@@ -157,6 +157,8 @@
bool consider_attack(int32_t);
+ void print_land_stats();
+
private:
// Variables of default AI
uint8_t type_;
@@ -169,6 +171,8 @@
std::vector<BuildingObserver> buildings_;
uint32_t num_constructionsites_;
+ uint32_t num_milit_constructionsites;
+ uint32_t num_prod_constructionsites;
std::list<Widelands::FCoords> unusable_fields;
std::list<BuildableField*> buildable_fields;
@@ -195,7 +199,7 @@
int32_t next_helpersites_check_due_;
int32_t inhibit_road_building_;
int32_t time_of_last_construction_;
- int32_t next_wood_cutting_check_due_;
+ int32_t enemy_last_seen_;
uint16_t numof_warehouses_;
@@ -206,8 +210,10 @@
uint16_t military_last_dismantle_;
int32_t military_last_build_; // sometimes expansions just stops, this is time of last military
// building build
+ int32_t spots_; // sum of buildable fields
- std::unique_ptr<Notifications::Subscriber<Widelands::NoteFieldPossession>> field_possession_subscriber_;
+ std::unique_ptr<Notifications::Subscriber<Widelands::NoteFieldPossession>>
+ field_possession_subscriber_;
std::unique_ptr<Notifications::Subscriber<Widelands::NoteImmovable>> immovable_subscriber_;
};
=== modified file 'tribes/atlanteans/armorsmithy/conf'
--- tribes/atlanteans/armorsmithy/conf 2014-05-27 14:14:14 +0000
+++ tribes/atlanteans/armorsmithy/conf 2014-07-29 20:53:33 +0000
@@ -3,7 +3,7 @@
output=steel_shield
[aihints]
-build_material=false
+prohibited_till=900
[buildcost]
log=2
=== modified file 'tribes/atlanteans/bakery/conf'
--- tribes/atlanteans/bakery/conf 2014-07-14 10:45:44 +0000
+++ tribes/atlanteans/bakery/conf 2014-07-29 20:53:33 +0000
@@ -2,8 +2,8 @@
output=bread
[aihints]
-build_material=false
-is_food_basic=true
+forced_after=1200
+prohibited_till=900
[buildcost]
log=2
=== modified file 'tribes/atlanteans/blackroot_farm/conf'
--- tribes/atlanteans/blackroot_farm/conf 2014-07-28 12:48:04 +0000
+++ tribes/atlanteans/blackroot_farm/conf 2014-07-29 20:53:33 +0000
@@ -2,8 +2,8 @@
output=blackroot
[aihints]
+prohibited_till=600
space_consumer=true
-build_material=false
[buildcost]
planks=3
=== modified file 'tribes/atlanteans/burners_house/conf'
--- tribes/atlanteans/burners_house/conf 2014-07-28 10:10:51 +0000
+++ tribes/atlanteans/burners_house/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=coal
[aihints]
-build_material=false
+prohibited_till=1200
[buildcost]
log=2
=== modified file 'tribes/atlanteans/castle/conf'
--- tribes/atlanteans/castle/conf 2014-07-28 12:48:04 +0000
+++ tribes/atlanteans/castle/conf 2014-07-29 20:53:33 +0000
@@ -13,6 +13,7 @@
expansion=true
fighting=true
mountain_conqueror=true
+prohibited_till=1800
[buildcost]
planks=4
=== modified file 'tribes/atlanteans/coalmine/conf'
--- tribes/atlanteans/coalmine/conf 2014-07-28 18:31:33 +0000
+++ tribes/atlanteans/coalmine/conf 2014-07-29 20:53:33 +0000
@@ -3,6 +3,7 @@
[aihints]
mines=coal
+prohibited_till=1200
[buildcost]
log=7
=== modified file 'tribes/atlanteans/cornflour/conf'
--- tribes/atlanteans/cornflour/conf 2014-07-28 14:04:36 +0000
+++ tribes/atlanteans/cornflour/conf 2014-07-29 20:53:33 +0000
@@ -1,7 +1,7 @@
help=_Cornflour is produced in a mill out of corn and is one of three parts of the Atlantean bread produced in bakeries.
default_target_quantity=15
-preciousness=2
+preciousness=7
[idle]
pics=idle.png
=== modified file 'tribes/atlanteans/crystalmine/conf'
--- tribes/atlanteans/crystalmine/conf 2014-07-28 18:31:33 +0000
+++ tribes/atlanteans/crystalmine/conf 2014-07-29 20:53:33 +0000
@@ -5,6 +5,7 @@
[aihints]
mines=granite
+prohibited_till=600
[buildcost]
log=7
=== modified file 'tribes/atlanteans/farm/conf'
--- tribes/atlanteans/farm/conf 2014-07-28 10:10:51 +0000
+++ tribes/atlanteans/farm/conf 2014-07-29 20:53:33 +0000
@@ -3,8 +3,9 @@
[aihints]
space_consumer=true
-is_basic=true # farm needs spidercloth to be build and spidercloth needs
+forced_after=180 # farm needs spidercloth to be build and spidercloth needs
# corn for production -> farm should be build ASAP!
+prohibited_till=120
[buildcost]
log=3
=== modified file 'tribes/atlanteans/fish_breeders_house/conf'
--- tribes/atlanteans/fish_breeders_house/conf 2014-07-28 10:10:51 +0000
+++ tribes/atlanteans/fish_breeders_house/conf 2014-07-29 20:53:33 +0000
@@ -1,9 +1,9 @@
size=small
[aihints]
-build_material=false
needs_water=true
renews_map_resource=fish
+prohibited_till=900
[buildcost]
log=1
=== modified file 'tribes/atlanteans/fishers_house/conf'
--- tribes/atlanteans/fishers_house/conf 2014-07-28 10:10:51 +0000
+++ tribes/atlanteans/fishers_house/conf 2014-07-29 20:53:33 +0000
@@ -2,8 +2,8 @@
output=fish
[aihints]
-build_material=false
needs_water=true
+prohibited_till=600
[buildcost]
log=1
=== modified file 'tribes/atlanteans/foresters_house/conf'
--- tribes/atlanteans/foresters_house/conf 2014-07-28 10:10:51 +0000
+++ tribes/atlanteans/foresters_house/conf 2014-07-29 20:53:33 +0000
@@ -3,6 +3,7 @@
[aihints]
space_consumer=true
renews_map_resource=log
+prohibited_till=50
[buildcost]
log=1
=== modified file 'tribes/atlanteans/gold-spinning-mill/conf'
--- tribes/atlanteans/gold-spinning-mill/conf 2014-07-15 05:12:37 +0000
+++ tribes/atlanteans/gold-spinning-mill/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=goldyarn
[aihints]
-build_material=false
+prohibited_till=600
[buildcost]
log=2
=== modified file 'tribes/atlanteans/goldmine/conf'
--- tribes/atlanteans/goldmine/conf 2014-07-28 18:31:33 +0000
+++ tribes/atlanteans/goldmine/conf 2014-07-29 20:53:33 +0000
@@ -2,8 +2,8 @@
output=goldore
[aihints]
-build_material=false
mines=gold
+prohibited_till=1200
[buildcost]
log=7
=== modified file 'tribes/atlanteans/horsefarm/conf'
--- tribes/atlanteans/horsefarm/conf 2014-07-14 10:45:44 +0000
+++ tribes/atlanteans/horsefarm/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,6 @@
output=horse
[aihints]
-build_material=false
recruitment=true
[buildcost]
=== modified file 'tribes/atlanteans/hunters_house/conf'
--- tribes/atlanteans/hunters_house/conf 2014-07-28 18:31:33 +0000
+++ tribes/atlanteans/hunters_house/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=meat
[aihints]
-build_material=false
+prohibited_till=60
[buildcost]
log=1
=== modified file 'tribes/atlanteans/ironmine/conf'
--- tribes/atlanteans/ironmine/conf 2014-07-28 18:31:33 +0000
+++ tribes/atlanteans/ironmine/conf 2014-07-29 20:53:33 +0000
@@ -2,8 +2,8 @@
output=ironore
[aihints]
-build_material=false
mines=iron
+prohibited_till=1200
[buildcost]
log=7
=== modified file 'tribes/atlanteans/labyrinth/conf'
--- tribes/atlanteans/labyrinth/conf 2014-03-17 17:23:26 +0000
+++ tribes/atlanteans/labyrinth/conf 2014-07-29 20:53:33 +0000
@@ -91,3 +91,6 @@
[idle]
pics=labyrinth_i_??.png # ???
hotspot=80 88
+
+[aihints]
+prohibited_till=2700
=== modified file 'tribes/atlanteans/mill/conf'
--- tribes/atlanteans/mill/conf 2014-07-28 10:10:51 +0000
+++ tribes/atlanteans/mill/conf 2014-07-29 20:53:33 +0000
@@ -3,7 +3,6 @@
output=blackrootflour
[aihints]
-build_material=false
[buildcost]
log=3
=== modified file 'tribes/atlanteans/quarry/conf'
--- tribes/atlanteans/quarry/conf 2014-07-28 10:10:51 +0000
+++ tribes/atlanteans/quarry/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=stone
[aihints]
-is_basic=true
+forced_after=60
stoneproducer=true
[buildcost]
=== modified file 'tribes/atlanteans/sawmill/conf'
--- tribes/atlanteans/sawmill/conf 2014-07-14 10:45:44 +0000
+++ tribes/atlanteans/sawmill/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,8 @@
output=planks
[aihints]
-is_basic=true
+forced_after=300
+prohibited_till=60
[buildcost]
log=2
=== modified file 'tribes/atlanteans/scouts_house/conf'
--- tribes/atlanteans/scouts_house/conf 2014-07-28 10:10:51 +0000
+++ tribes/atlanteans/scouts_house/conf 2014-07-29 20:53:33 +0000
@@ -1,7 +1,6 @@
size=small
[aihints]
-build_material=false
[buildcost]
log=2
=== modified file 'tribes/atlanteans/shipyard/conf'
--- tribes/atlanteans/shipyard/conf 2014-03-17 17:23:26 +0000
+++ tribes/atlanteans/shipyard/conf 2014-07-29 20:53:33 +0000
@@ -1,7 +1,6 @@
size=medium
[aihints]
-build_material=false
needs_water=true
[buildcost]
=== modified file 'tribes/atlanteans/smelting_works/conf'
--- tribes/atlanteans/smelting_works/conf 2014-07-28 10:10:51 +0000
+++ tribes/atlanteans/smelting_works/conf 2014-07-29 20:53:33 +0000
@@ -3,7 +3,7 @@
output=gold
[aihints]
-build_material=false
+prohibited_till=600
[buildcost]
log=1
=== modified file 'tribes/atlanteans/smokery/conf'
--- tribes/atlanteans/smokery/conf 2014-07-28 10:10:51 +0000
+++ tribes/atlanteans/smokery/conf 2014-07-29 20:53:33 +0000
@@ -3,8 +3,8 @@
output=smoked_fish
[aihints]
-build_material=false
-is_food_basic=true
+forced_after=900
+prohibited_till=60
[buildcost]
log=1
=== modified file 'tribes/atlanteans/spidercloth/conf'
--- tribes/atlanteans/spidercloth/conf 2014-07-28 14:04:36 +0000
+++ tribes/atlanteans/spidercloth/conf 2014-07-29 20:53:33 +0000
@@ -1,7 +1,7 @@
help=_Spidercloth is made out of spideryarn in a weaving mill. It is used in the toolsmithy and the shipyard. Also some higher developed buildings need spidercloth for their construction.
default_target_quantity=20
-preciousness=1
+preciousness=5
[idle]
pics=idle.png
=== modified file 'tribes/atlanteans/spiderfarm/conf'
--- tribes/atlanteans/spiderfarm/conf 2014-07-28 10:10:51 +0000
+++ tribes/atlanteans/spiderfarm/conf 2014-07-29 20:53:33 +0000
@@ -34,3 +34,7 @@
[working]
pics=spiderfarm_i_??.png # ???
hotspot=87 75
+
+[aihints]
+forced_after=60
+prohibited_till=60
=== modified file 'tribes/atlanteans/spideryarn/conf'
--- tribes/atlanteans/spideryarn/conf 2014-04-08 06:28:45 +0000
+++ tribes/atlanteans/spideryarn/conf 2014-07-29 20:53:33 +0000
@@ -1,7 +1,7 @@
help=_This yarn is produced by spiders, which are bred by spider farms. It is processed into spidercloth in a weaving mill.
default_target_quantity=10
-preciousness=2
+preciousness=11
[idle]
pics=idle.png
=== modified file 'tribes/atlanteans/toolsmithy/conf'
--- tribes/atlanteans/toolsmithy/conf 2014-07-28 10:10:51 +0000
+++ tribes/atlanteans/toolsmithy/conf 2014-07-29 20:53:33 +0000
@@ -13,8 +13,8 @@
output=shovel
[aihints]
-build_material=false
-is_basic=true
+forced_after=900
+prohibited_till=450
[buildcost]
log=1
=== modified file 'tribes/atlanteans/tower/conf'
--- tribes/atlanteans/tower/conf 2014-07-28 12:48:04 +0000
+++ tribes/atlanteans/tower/conf 2014-07-29 20:53:33 +0000
@@ -14,6 +14,7 @@
[aihints]
expansion=true
mountain_conqueror=true
+prohibited_till=600
[buildcost]
log=2
=== modified file 'tribes/atlanteans/weaponsmithy/conf'
--- tribes/atlanteans/weaponsmithy/conf 2014-07-15 10:02:22 +0000
+++ tribes/atlanteans/weaponsmithy/conf 2014-07-29 20:53:33 +0000
@@ -6,7 +6,7 @@
output=heavy_double_trident
[aihints]
-build_material=false
+prohibited_till=900
[buildcost]
log=2
=== modified file 'tribes/atlanteans/weaving-mill/conf'
--- tribes/atlanteans/weaving-mill/conf 2014-07-28 10:10:51 +0000
+++ tribes/atlanteans/weaving-mill/conf 2014-07-29 20:53:33 +0000
@@ -4,7 +4,8 @@
output=golden_tabard
[aihints]
-is_basic=true
+forced_after=60
+prohibited_till=60
[buildcost]
log=3
=== modified file 'tribes/atlanteans/well/conf'
--- tribes/atlanteans/well/conf 2014-07-28 10:10:51 +0000
+++ tribes/atlanteans/well/conf 2014-07-29 20:53:33 +0000
@@ -3,6 +3,8 @@
[aihints]
mines_water=true
+forced_after=600
+prohibited_till=300
[buildcost]
log=2
=== modified file 'tribes/atlanteans/woodcutters_house/conf'
--- tribes/atlanteans/woodcutters_house/conf 2014-07-28 12:48:04 +0000
+++ tribes/atlanteans/woodcutters_house/conf 2014-07-29 20:53:33 +0000
@@ -2,8 +2,8 @@
output=log
[aihints]
-is_basic=true
logproducer=true
+forced_after=0
[buildcost]
log=2
=== modified file 'tribes/barbarians/axfactory/conf'
--- tribes/barbarians/axfactory/conf 2014-07-28 12:48:04 +0000
+++ tribes/barbarians/axfactory/conf 2014-07-29 20:53:33 +0000
@@ -7,7 +7,6 @@
enhancement=warmill
[aihints]
-build_material=false
[enhancement_cost]
log=1
=== modified file 'tribes/barbarians/bakery/conf'
--- tribes/barbarians/bakery/conf 2014-07-28 10:10:51 +0000
+++ tribes/barbarians/bakery/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=pittabread
[aihints]
-build_material=false
+prohibited_till=600
[buildcost]
log=2
=== modified file 'tribes/barbarians/burners_house/conf'
--- tribes/barbarians/burners_house/conf 2014-07-28 10:10:51 +0000
+++ tribes/barbarians/burners_house/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=coal
[aihints]
-build_material=false
+prohibited_till=900
[buildcost]
log=3
=== modified file 'tribes/barbarians/cattlefarm/conf'
--- tribes/barbarians/cattlefarm/conf 2014-07-14 10:45:44 +0000
+++ tribes/barbarians/cattlefarm/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,6 @@
output=ox
[aihints]
-build_material=false
recruitment=true
[buildcost]
=== modified file 'tribes/barbarians/coalmine/conf'
--- tribes/barbarians/coalmine/conf 2014-07-28 10:10:51 +0000
+++ tribes/barbarians/coalmine/conf 2014-07-29 20:53:33 +0000
@@ -5,6 +5,7 @@
[aihints]
mines=coal
mines_percent=30
+prohibited_till=1200
[buildcost]
log=4
=== modified file 'tribes/barbarians/donjon/conf'
--- tribes/barbarians/donjon/conf 2014-07-28 12:48:04 +0000
+++ tribes/barbarians/donjon/conf 2014-07-29 20:53:33 +0000
@@ -14,6 +14,7 @@
expansion=true
fighting=true
mountain_conqueror=true
+prohibited_till=1500
[buildcost]
blackwood=7
=== modified file 'tribes/barbarians/fishers_hut/conf'
--- tribes/barbarians/fishers_hut/conf 2014-07-28 10:10:51 +0000
+++ tribes/barbarians/fishers_hut/conf 2014-07-29 20:53:33 +0000
@@ -2,8 +2,8 @@
output=fish
[aihints]
-build_material=false
needs_water=true
+prohibited_till=900
[buildcost]
log=4
=== modified file 'tribes/barbarians/fortress/conf'
--- tribes/barbarians/fortress/conf 2014-07-28 12:48:04 +0000
+++ tribes/barbarians/fortress/conf 2014-07-29 20:53:33 +0000
@@ -14,6 +14,7 @@
expansion=true
fighting=true
mountain_conqueror=true
+prohibited_till=1800
[buildcost]
blackwood=9
=== modified file 'tribes/barbarians/gamekeepers_hut/conf'
--- tribes/barbarians/gamekeepers_hut/conf 2014-07-28 10:10:51 +0000
+++ tribes/barbarians/gamekeepers_hut/conf 2014-07-29 20:53:33 +0000
@@ -1,8 +1,8 @@
size=small
[aihints]
-build_material=false
renews_map_resource=meat
+prohibited_till=900
[buildcost]
log=4
=== modified file 'tribes/barbarians/goldmine/conf'
--- tribes/barbarians/goldmine/conf 2014-07-28 10:10:51 +0000
+++ tribes/barbarians/goldmine/conf 2014-07-29 20:53:33 +0000
@@ -3,9 +3,9 @@
enhancement=deep_goldmine
[aihints]
-build_material=false
mines=gold
mines_percent=30
+prohibited_till=1200
[buildcost]
log=4
=== modified file 'tribes/barbarians/granitemine/conf'
--- tribes/barbarians/granitemine/conf 2014-07-28 10:10:51 +0000
+++ tribes/barbarians/granitemine/conf 2014-07-29 20:53:33 +0000
@@ -3,6 +3,7 @@
[aihints]
mines=granite
+prohibited_till=900
[buildcost]
log=4
=== modified file 'tribes/barbarians/hardener/conf'
--- tribes/barbarians/hardener/conf 2014-07-14 10:45:44 +0000
+++ tribes/barbarians/hardener/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=blackwood
[aihints]
-is_basic=true
+forced_after=0
[buildcost]
log=3
=== modified file 'tribes/barbarians/helmsmithy/conf'
--- tribes/barbarians/helmsmithy/conf 2014-07-14 10:45:44 +0000
+++ tribes/barbarians/helmsmithy/conf 2014-07-29 20:53:33 +0000
@@ -4,7 +4,7 @@
output=warhelm
[aihints]
-build_material=false
+prohibited_till=1200
[buildcost]
log=3
=== modified file 'tribes/barbarians/hunters_hut/conf'
--- tribes/barbarians/hunters_hut/conf 2014-07-28 10:10:51 +0000
+++ tribes/barbarians/hunters_hut/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=meat
[aihints]
-build_material=false
+prohibited_till=300
[buildcost]
log=4
=== modified file 'tribes/barbarians/lumberjacks_hut/conf'
--- tribes/barbarians/lumberjacks_hut/conf 2014-07-28 10:10:51 +0000
+++ tribes/barbarians/lumberjacks_hut/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=log
[aihints]
-is_basic=true
+forced_after=0
logproducer=true
[buildcost]
=== modified file 'tribes/barbarians/metalworks/conf'
--- tribes/barbarians/metalworks/conf 2014-07-28 12:48:04 +0000
+++ tribes/barbarians/metalworks/conf 2014-07-29 20:53:33 +0000
@@ -12,8 +12,8 @@
enhancement=axfactory
[aihints]
-build_material=false
-is_basic=true
+forced_after=300
+prohibited_till=120
[buildcost]
log=1
=== modified file 'tribes/barbarians/micro-brewery/conf'
--- tribes/barbarians/micro-brewery/conf 2014-07-14 10:45:44 +0000
+++ tribes/barbarians/micro-brewery/conf 2014-07-29 20:53:33 +0000
@@ -3,7 +3,7 @@
enhancement=brewery
[aihints]
-build_material=false
+prohibited_till=600
[buildcost]
log=3
=== modified file 'tribes/barbarians/oremine/conf'
--- tribes/barbarians/oremine/conf 2014-07-28 10:10:51 +0000
+++ tribes/barbarians/oremine/conf 2014-07-29 20:53:33 +0000
@@ -3,8 +3,8 @@
enhancement=deep_oremine
[aihints]
-build_material=false
mines=iron
+prohibited_till=1200
mines_percent=30
[buildcost]
=== modified file 'tribes/barbarians/quarry/conf'
--- tribes/barbarians/quarry/conf 2014-07-28 10:10:51 +0000
+++ tribes/barbarians/quarry/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=raw_stone
[aihints]
-is_basic=true
+forced_after=0
stoneproducer=true
[buildcost]
=== modified file 'tribes/barbarians/reed_yard/conf'
--- tribes/barbarians/reed_yard/conf 2014-07-22 12:29:17 +0000
+++ tribes/barbarians/reed_yard/conf 2014-07-29 20:53:33 +0000
@@ -3,6 +3,7 @@
[aihints]
space_consumer=true
+forced_after=0
[buildcost]
log=5
=== modified file 'tribes/barbarians/scouts_hut/conf'
--- tribes/barbarians/scouts_hut/conf 2014-07-28 10:10:51 +0000
+++ tribes/barbarians/scouts_hut/conf 2014-07-29 20:53:33 +0000
@@ -1,7 +1,6 @@
size=small
[aihints]
-build_material=false
[buildcost]
log=2
=== modified file 'tribes/barbarians/shipyard/conf'
--- tribes/barbarians/shipyard/conf 2014-07-28 12:48:04 +0000
+++ tribes/barbarians/shipyard/conf 2014-07-29 20:53:33 +0000
@@ -1,7 +1,6 @@
size=medium
[aihints]
-build_material=false
needs_water=true
[buildcost]
=== modified file 'tribes/barbarians/smelting_works/conf'
--- tribes/barbarians/smelting_works/conf 2014-07-14 10:45:44 +0000
+++ tribes/barbarians/smelting_works/conf 2014-07-29 20:53:33 +0000
@@ -3,7 +3,7 @@
output=gold
[aihints]
-build_material=false
+prohibited_till=300
[buildcost]
log=3
=== modified file 'tribes/barbarians/tavern/conf'
--- tribes/barbarians/tavern/conf 2014-07-28 14:04:36 +0000
+++ tribes/barbarians/tavern/conf 2014-07-29 20:53:33 +0000
@@ -3,8 +3,7 @@
enhancement=inn
[aihints]
-build_material=false
-is_food_basic=true
+forced_after=900
[buildcost]
log=3
=== modified file 'tribes/barbarians/trainingcamp/conf'
--- tribes/barbarians/trainingcamp/conf 2014-07-28 12:48:04 +0000
+++ tribes/barbarians/trainingcamp/conf 2014-07-29 20:53:33 +0000
@@ -35,6 +35,9 @@
min_level=0
max_level=4
+[aihints]
+prohibited_till=2700
+
[soldier hp]
min_level=0
max_level=2
=== modified file 'tribes/barbarians/warmill/conf'
--- tribes/barbarians/warmill/conf 2014-07-28 12:48:04 +0000
+++ tribes/barbarians/warmill/conf 2014-07-29 20:53:33 +0000
@@ -9,7 +9,6 @@
enhanced_building=yes
[aihints]
-build_material=false
[enhancement_cost]
log=1
=== modified file 'tribes/barbarians/weaving-mill/conf'
--- tribes/barbarians/weaving-mill/conf 2014-07-15 10:02:22 +0000
+++ tribes/barbarians/weaving-mill/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=cloth
[aihints]
-build_material=false
+prohibited_till=1200
[buildcost]
log=5
=== modified file 'tribes/barbarians/well/conf'
--- tribes/barbarians/well/conf 2014-07-28 10:10:51 +0000
+++ tribes/barbarians/well/conf 2014-07-29 20:53:33 +0000
@@ -2,8 +2,8 @@
output=water
[aihints]
-build_material=false
mines_water=true
+prohibited_till=600
[buildcost]
log=4
=== modified file 'tribes/empire/armorsmithy/conf'
--- tribes/empire/armorsmithy/conf 2014-07-14 10:45:44 +0000
+++ tribes/empire/armorsmithy/conf 2014-07-29 20:53:33 +0000
@@ -5,7 +5,7 @@
output=plate_armor
[aihints]
-build_material=false
+prohibited_till=900
[buildcost]
log=2
=== modified file 'tribes/empire/bakery/conf'
--- tribes/empire/bakery/conf 2014-07-28 12:48:04 +0000
+++ tribes/empire/bakery/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=bread
[aihints]
-build_material=false
+prohibited_till=600
[buildcost]
log=2
=== modified file 'tribes/empire/beer/conf'
--- tribes/empire/beer/conf 2013-07-23 19:04:12 +0000
+++ tribes/empire/beer/conf 2014-07-29 20:53:33 +0000
@@ -1,7 +1,7 @@
help=_This beer is produced in a brewery out of wheat and water. It is consumed by miners in coal and iron ore mines.
default_target_quantity=15
-preciousness=2
+preciousness=5
[idle]
pics=idle.png
=== modified file 'tribes/empire/brewery/conf'
--- tribes/empire/brewery/conf 2014-07-28 10:10:51 +0000
+++ tribes/empire/brewery/conf 2014-07-29 20:53:33 +0000
@@ -2,8 +2,8 @@
output=beer
[aihints]
-build_material=false
-is_food_basic=true
+forced_after=900
+prohibited_till=600
[buildcost]
log=1
=== modified file 'tribes/empire/burners_house/conf'
--- tribes/empire/burners_house/conf 2014-07-28 10:10:51 +0000
+++ tribes/empire/burners_house/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=coal
[aihints]
-build_material=false
+prohibited_till=600
[buildcost]
log=2
=== modified file 'tribes/empire/coalmine/conf'
--- tribes/empire/coalmine/conf 2014-07-28 10:10:51 +0000
+++ tribes/empire/coalmine/conf 2014-07-29 20:53:33 +0000
@@ -5,6 +5,7 @@
[aihints]
mines=coal
mines_percent=50
+prohibited_till=1200
[buildcost]
log=4
=== modified file 'tribes/empire/donkeyfarm/conf'
--- tribes/empire/donkeyfarm/conf 2014-07-14 10:45:44 +0000
+++ tribes/empire/donkeyfarm/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,6 @@
output=donkey
[aihints]
-build_material=false
recruitment=true
[buildcost]
=== modified file 'tribes/empire/farm/conf'
--- tribes/empire/farm/conf 2014-07-22 12:29:17 +0000
+++ tribes/empire/farm/conf 2014-07-29 20:53:33 +0000
@@ -3,7 +3,7 @@
[aihints]
space_consumer=true
-is_food_basic=true
+forced_after=900
[buildcost]
wood=2
=== modified file 'tribes/empire/fishers_house/conf'
--- tribes/empire/fishers_house/conf 2014-07-28 10:10:51 +0000
+++ tribes/empire/fishers_house/conf 2014-07-29 20:53:33 +0000
@@ -2,8 +2,8 @@
output=fish
[aihints]
-build_material=false
needs_water=true
+prohibited_till=600
[buildcost]
log=1
=== modified file 'tribes/empire/flour/conf'
--- tribes/empire/flour/conf 2013-07-23 19:04:12 +0000
+++ tribes/empire/flour/conf 2014-07-29 20:53:33 +0000
@@ -1,7 +1,7 @@
help=_Flour is produced by the mill out of wheat and is needed in the bakery to produce the tasty Empire bread.
default_target_quantity=20
-preciousness=3
+preciousness=5
[idle]
pics=flour_idle.png
=== modified file 'tribes/empire/fortress/conf'
--- tribes/empire/fortress/conf 2014-07-28 12:48:04 +0000
+++ tribes/empire/fortress/conf 2014-07-29 20:53:33 +0000
@@ -14,6 +14,7 @@
expansion=true
fighting=true
mountain_conqueror=true
+prohibited_till=1500
[buildcost]
wood=5
=== modified file 'tribes/empire/goldmine/conf'
--- tribes/empire/goldmine/conf 2014-07-28 10:10:51 +0000
+++ tribes/empire/goldmine/conf 2014-07-29 20:53:33 +0000
@@ -3,9 +3,9 @@
enhancement=deep_goldmine
[aihints]
-build_material=false
mines=gold
mines_percent=50
+prohibited_till=1200
[buildcost]
log=4
=== modified file 'tribes/empire/hunters_house/conf'
--- tribes/empire/hunters_house/conf 2014-07-28 10:10:51 +0000
+++ tribes/empire/hunters_house/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,6 @@
output=meat
[aihints]
-build_material=false
[buildcost]
log=1
=== modified file 'tribes/empire/lumberjacks_house/conf'
--- tribes/empire/lumberjacks_house/conf 2014-07-28 10:10:51 +0000
+++ tribes/empire/lumberjacks_house/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=log
[aihints]
-is_basic=true
+forced_after=0
logproducer=true
[buildcost]
=== modified file 'tribes/empire/marblemine/conf'
--- tribes/empire/marblemine/conf 2014-07-28 10:10:51 +0000
+++ tribes/empire/marblemine/conf 2014-07-29 20:53:33 +0000
@@ -6,7 +6,7 @@
[aihints]
mines=granite
mines_percent=50
-marbleproducer=true
+prohibited_till=450
[buildcost]
log=4
=== modified file 'tribes/empire/mill/conf'
--- tribes/empire/mill/conf 2014-07-28 12:48:04 +0000
+++ tribes/empire/mill/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=flour
[aihints]
-build_material=false
+prohibited_till=600
[buildcost]
log=3
=== modified file 'tribes/empire/oremine/conf'
--- tribes/empire/oremine/conf 2014-07-28 10:10:51 +0000
+++ tribes/empire/oremine/conf 2014-07-29 20:53:33 +0000
@@ -3,9 +3,9 @@
enhancement=deep_oremine
[aihints]
-build_material=false
mines=iron
mines_percent=50
+prohibited_till=1200
[buildcost]
log=4
=== modified file 'tribes/empire/outpost/conf'
--- tribes/empire/outpost/conf 2014-07-28 12:48:04 +0000
+++ tribes/empire/outpost/conf 2014-07-29 20:53:33 +0000
@@ -12,6 +12,7 @@
[aihints]
expansion=true
+prohibited_till=600
[buildcost]
log=1
=== modified file 'tribes/empire/piggery/conf'
--- tribes/empire/piggery/conf 2014-07-28 10:10:51 +0000
+++ tribes/empire/piggery/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,6 @@
output=meat
[aihints]
-build_material=false
[buildcost]
log=2
=== modified file 'tribes/empire/quarry/conf'
--- tribes/empire/quarry/conf 2014-07-28 10:10:51 +0000
+++ tribes/empire/quarry/conf 2014-07-29 20:53:33 +0000
@@ -3,7 +3,7 @@
output=marble
[aihints]
-is_basic=true
+forced_after=0
stoneproducer=true
[buildcost]
=== modified file 'tribes/empire/sawmill/conf'
--- tribes/empire/sawmill/conf 2014-07-14 10:45:44 +0000
+++ tribes/empire/sawmill/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,8 @@
output=wood
[aihints]
-is_basic=true
+forced_after=60
+prohibited_till=60
[buildcost]
log=2
=== modified file 'tribes/empire/scouts_house/conf'
--- tribes/empire/scouts_house/conf 2014-07-28 10:10:51 +0000
+++ tribes/empire/scouts_house/conf 2014-07-29 20:53:33 +0000
@@ -1,7 +1,6 @@
size=small
[aihints]
-build_material=false
[buildcost]
log=2
=== modified file 'tribes/empire/sheepfarm/conf'
--- tribes/empire/sheepfarm/conf 2014-07-14 10:45:44 +0000
+++ tribes/empire/sheepfarm/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,7 @@
output=wool
[aihints]
-build_material=false
+prohibited_till=600
[buildcost]
log=2
@@ -38,3 +38,4 @@
[working]
pics=sheepfarm_i_??.png # ???
hotspot=73 60
+
=== modified file 'tribes/empire/shipyard/conf'
--- tribes/empire/shipyard/conf 2014-03-17 17:23:26 +0000
+++ tribes/empire/shipyard/conf 2014-07-29 20:53:33 +0000
@@ -1,7 +1,6 @@
size=medium
[aihints]
-build_material=false
needs_water=true
[buildcost]
=== modified file 'tribes/empire/smelting_works/conf'
--- tribes/empire/smelting_works/conf 2014-07-28 12:48:04 +0000
+++ tribes/empire/smelting_works/conf 2014-07-29 20:53:33 +0000
@@ -3,7 +3,7 @@
output=gold
[aihints]
-build_material=false
+prohibited_till=600
[buildcost]
log=1
=== modified file 'tribes/empire/stonemasons_house/conf'
--- tribes/empire/stonemasons_house/conf 2014-07-15 10:02:22 +0000
+++ tribes/empire/stonemasons_house/conf 2014-07-29 20:53:33 +0000
@@ -2,7 +2,8 @@
output=marblecolumn
[aihints]
-is_basic=true
+forced_after=300
+prohibited_till=120
[buildcost]
log=1
=== modified file 'tribes/empire/tavern/conf'
--- tribes/empire/tavern/conf 2014-07-28 10:10:51 +0000
+++ tribes/empire/tavern/conf 2014-07-29 20:53:33 +0000
@@ -3,8 +3,8 @@
enhancement=inn
[aihints]
-build_material=false
-is_food_basic=true
+forced_after=900
+prohibited_till=300
[buildcost]
wood=2
=== modified file 'tribes/empire/toolsmithy/conf'
--- tribes/empire/toolsmithy/conf 2014-07-28 12:48:04 +0000
+++ tribes/empire/toolsmithy/conf 2014-07-29 20:53:33 +0000
@@ -13,8 +13,8 @@
output=saw
[aihints]
-build_material=false
-is_basic=true
+forced_after=1200
+prohibited_till=120
[buildcost]
log=1
=== modified file 'tribes/empire/tower/conf'
--- tribes/empire/tower/conf 2014-07-28 12:48:04 +0000
+++ tribes/empire/tower/conf 2014-07-29 20:53:33 +0000
@@ -12,6 +12,7 @@
[aihints]
mountain_conqueror=true
+prohibited_till=300
[buildcost]
log=2
=== modified file 'tribes/empire/trainingcamp/conf'
--- tribes/empire/trainingcamp/conf 2014-03-17 17:23:26 +0000
+++ tribes/empire/trainingcamp/conf 2014-07-29 20:53:33 +0000
@@ -116,3 +116,6 @@
[idle]
pics=trainingcamp_i_??.png # ???
hotspot=82 105
+
+[aihints]
+prohibited_till=2700
=== modified file 'tribes/empire/vineyard/conf'
--- tribes/empire/vineyard/conf 2014-07-22 12:29:17 +0000
+++ tribes/empire/vineyard/conf 2014-07-29 20:53:33 +0000
@@ -3,9 +3,7 @@
[aihints]
space_consumer=true
-is_basic=true
-build_material=false
-is_food_basic=true
+forced_after=120
[buildcost]
wood=2
=== modified file 'tribes/empire/weaponsmithy/conf'
--- tribes/empire/weaponsmithy/conf 2014-07-14 10:45:44 +0000
+++ tribes/empire/weaponsmithy/conf 2014-07-29 20:53:33 +0000
@@ -6,7 +6,7 @@
output=war_lance
[aihints]
-build_material=false
+prohibited_till=900
[buildcost]
log=2
=== modified file 'tribes/empire/weaving-mill/conf'
--- tribes/empire/weaving-mill/conf 2014-07-28 12:48:04 +0000
+++ tribes/empire/weaving-mill/conf 2014-07-29 20:53:33 +0000
@@ -42,3 +42,6 @@
pics=weaving_mill_w_??.png # ???
hotspot=65 62
fps=5
+
+[aihints]
+prohibited_till=120
=== modified file 'tribes/empire/well/conf'
--- tribes/empire/well/conf 2014-07-28 10:10:51 +0000
+++ tribes/empire/well/conf 2014-07-29 20:53:33 +0000
@@ -2,8 +2,8 @@
output=water
[aihints]
-build_material=false
mines_water=true
+prohibited_till=60
[buildcost]
log=2
=== modified file 'tribes/empire/wine/conf'
--- tribes/empire/wine/conf 2014-07-28 14:04:36 +0000
+++ tribes/empire/wine/conf 2014-07-29 20:53:33 +0000
@@ -1,7 +1,7 @@
help=_This tasty wine is drunk by the miners working the marble and gold mines. It is produced in a winery.
default_target_quantity=20 # currently not used
-preciousness=2
+preciousness=5
[idle]
pics=idle.png
=== modified file 'tribes/empire/winery/conf'
--- tribes/empire/winery/conf 2014-07-15 10:02:22 +0000
+++ tribes/empire/winery/conf 2014-07-29 20:53:33 +0000
@@ -2,8 +2,8 @@
output=wine
[aihints]
-build_material=false
-is_food_basic=true
+forced_after=900
+prohibited_till=60
[buildcost]
wood=1
Follow ups
-
[Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: noreply, 2014-10-11
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: SirVer, 2014-10-11
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: TiborB, 2014-10-08
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: GunChleoc, 2014-10-08
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: Tibor Bamhor, 2014-10-07
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: GunChleoc, 2014-10-06
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: Tibor Bamhor, 2014-10-05
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: SirVer, 2014-10-05
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: SirVer, 2014-10-04
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: GunChleoc, 2014-10-04
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: GunChleoc, 2014-10-04
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: Tibor Bamhor, 2014-09-26
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: Tibor Bamhor, 2014-09-08
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: SirVer, 2014-09-08
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: Tibor Bamhor, 2014-09-08
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: Tibor Bamhor, 2014-09-08
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: Tibor Bamhor, 2014-09-08
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: Tibor Bamhor, 2014-09-08
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: GunChleoc, 2014-09-08
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: Tibor Bamhor, 2014-09-07
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: Tibor Bamhor, 2014-09-07
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: GunChleoc, 2014-09-07
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: GunChleoc, 2014-09-07
-
Re: [Merge] lp:~widelands-dev/widelands/tibor-ai5 into lp:widelands
From: SirVer, 2014-08-02