|
@@ -1352,6 +1352,7 @@ bool VCAI::tryBuildNextStructure(const CGTownInstance * t, std::vector<BuildingI
|
|
|
//Set of buildings for different goals. Does not include any prerequisites.
|
|
//Set of buildings for different goals. Does not include any prerequisites.
|
|
|
static const BuildingID essential[] = {BuildingID::TAVERN, BuildingID::TOWN_HALL};
|
|
static const BuildingID essential[] = {BuildingID::TAVERN, BuildingID::TOWN_HALL};
|
|
|
static const BuildingID goldSource[] = {BuildingID::TOWN_HALL, BuildingID::CITY_HALL, BuildingID::CAPITOL};
|
|
static const BuildingID goldSource[] = {BuildingID::TOWN_HALL, BuildingID::CITY_HALL, BuildingID::CAPITOL};
|
|
|
|
|
+static const BuildingID capitolRequirements[] = { BuildingID::FORT, BuildingID::CITADEL };
|
|
|
static const BuildingID unitsSource[] = { BuildingID::DWELL_LVL_1, BuildingID::DWELL_LVL_2, BuildingID::DWELL_LVL_3,
|
|
static const BuildingID unitsSource[] = { BuildingID::DWELL_LVL_1, BuildingID::DWELL_LVL_2, BuildingID::DWELL_LVL_3,
|
|
|
BuildingID::DWELL_LVL_4, BuildingID::DWELL_LVL_5, BuildingID::DWELL_LVL_6, BuildingID::DWELL_LVL_7};
|
|
BuildingID::DWELL_LVL_4, BuildingID::DWELL_LVL_5, BuildingID::DWELL_LVL_6, BuildingID::DWELL_LVL_7};
|
|
|
static const BuildingID unitsUpgrade[] = { BuildingID::DWELL_LVL_1_UP, BuildingID::DWELL_LVL_2_UP, BuildingID::DWELL_LVL_3_UP,
|
|
static const BuildingID unitsUpgrade[] = { BuildingID::DWELL_LVL_1_UP, BuildingID::DWELL_LVL_2_UP, BuildingID::DWELL_LVL_3_UP,
|
|
@@ -1370,55 +1371,64 @@ void VCAI::buildStructure(const CGTownInstance * t)
|
|
|
//TODO: build resource silo, defences when needed
|
|
//TODO: build resource silo, defences when needed
|
|
|
//Possible - allow "locking" on specific building (build prerequisites and then building itself)
|
|
//Possible - allow "locking" on specific building (build prerequisites and then building itself)
|
|
|
|
|
|
|
|
|
|
+ //below algorithm focuses on economy growth at start of the game.
|
|
|
TResources currentRes = cb->getResourceAmount();
|
|
TResources currentRes = cb->getResourceAmount();
|
|
|
TResources currentIncome = t->dailyIncome();
|
|
TResources currentIncome = t->dailyIncome();
|
|
|
int townIncome = currentIncome[Res::GOLD];
|
|
int townIncome = currentIncome[Res::GOLD];
|
|
|
|
|
|
|
|
- if (tryBuildAnyStructure(t, std::vector<BuildingID>(essential, essential + ARRAY_COUNT(essential))))
|
|
|
|
|
|
|
+ if(tryBuildAnyStructure(t, std::vector<BuildingID>(essential, essential + ARRAY_COUNT(essential))))
|
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
- //we're running out of gold - try to build something gold-producing. Multiplier can be tweaked, 6 is minimum due to buildings costs
|
|
|
|
|
- if (currentRes[Res::GOLD] < townIncome * 6)
|
|
|
|
|
- if (tryBuildNextStructure(t, std::vector<BuildingID>(goldSource, goldSource + ARRAY_COUNT(goldSource))))
|
|
|
|
|
|
|
+ //the more gold the better and less problems later
|
|
|
|
|
+ if(tryBuildNextStructure(t, std::vector<BuildingID>(goldSource, goldSource + ARRAY_COUNT(goldSource))))
|
|
|
|
|
+ return;
|
|
|
|
|
+
|
|
|
|
|
+ //workaround for mantis #2696 - build fort and citadel - building castle will be handled without bug
|
|
|
|
|
+ if(vstd::contains(t->builtBuildings, BuildingID::CITY_HALL) && cb->canBuildStructure(t, BuildingID::CAPITOL) != EBuildingState::HAVE_CAPITAL &&
|
|
|
|
|
+ cb->canBuildStructure(t, BuildingID::CAPITOL) != EBuildingState::FORBIDDEN)
|
|
|
|
|
+ if(tryBuildNextStructure(t, std::vector<BuildingID>(capitolRequirements, capitolRequirements + ARRAY_COUNT(capitolRequirements))))
|
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
- if (cb->getDate(Date::DAY_OF_WEEK) > 6)// last 2 days of week - try to focus on growth
|
|
|
|
|
|
|
+ if((!vstd::contains(t->builtBuildings, BuildingID::CAPITOL) && cb->canBuildStructure(t, BuildingID::CAPITOL) != EBuildingState::HAVE_CAPITAL && cb->canBuildStructure(t, BuildingID::CAPITOL) != EBuildingState::FORBIDDEN)
|
|
|
|
|
+ || (!vstd::contains(t->builtBuildings, BuildingID::CITY_HALL) && cb->canBuildStructure(t, BuildingID::CAPITOL) == EBuildingState::HAVE_CAPITAL && cb->canBuildStructure(t, BuildingID::CITY_HALL) != EBuildingState::FORBIDDEN)
|
|
|
|
|
+ || (!vstd::contains(t->builtBuildings, BuildingID::TOWN_HALL) && cb->canBuildStructure(t, BuildingID::TOWN_HALL) != EBuildingState::FORBIDDEN))
|
|
|
|
|
+ return; //save money for capitol or city hall if capitol unavailable, do not build other things (unless gold source buildings are disabled in map editor)
|
|
|
|
|
+
|
|
|
|
|
+ if(cb->getDate(Date::DAY_OF_WEEK) > 6)// last 2 days of week - try to focus on growth
|
|
|
{
|
|
{
|
|
|
- if (tryBuildNextStructure(t, std::vector<BuildingID>(unitGrowth, unitGrowth + ARRAY_COUNT(unitGrowth)), 2))
|
|
|
|
|
|
|
+ if(tryBuildNextStructure(t, std::vector<BuildingID>(unitGrowth, unitGrowth + ARRAY_COUNT(unitGrowth)), 2))
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// first in-game week or second half of any week: try build dwellings
|
|
// first in-game week or second half of any week: try build dwellings
|
|
|
- if (cb->getDate(Date::DAY) < 7 || cb->getDate(Date::DAY_OF_WEEK) > 3)
|
|
|
|
|
- if (tryBuildAnyStructure(t, std::vector<BuildingID>(unitsSource, unitsSource + ARRAY_COUNT(unitsSource)), 8 - cb->getDate(Date::DAY_OF_WEEK)))
|
|
|
|
|
|
|
+ if(cb->getDate(Date::DAY) < 7 || cb->getDate(Date::DAY_OF_WEEK) > 3)
|
|
|
|
|
+ if(tryBuildAnyStructure(t, std::vector<BuildingID>(unitsSource, unitsSource + ARRAY_COUNT(unitsSource)), 8 - cb->getDate(Date::DAY_OF_WEEK)))
|
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
//try to upgrade dwelling
|
|
//try to upgrade dwelling
|
|
|
for(int i = 0; i < ARRAY_COUNT(unitsUpgrade); i++)
|
|
for(int i = 0; i < ARRAY_COUNT(unitsUpgrade); i++)
|
|
|
{
|
|
{
|
|
|
- if (t->hasBuilt(unitsSource[i]) && !t->hasBuilt(unitsUpgrade[i]))
|
|
|
|
|
|
|
+ if(t->hasBuilt(unitsSource[i]) && !t->hasBuilt(unitsUpgrade[i]))
|
|
|
{
|
|
{
|
|
|
- if (tryBuildStructure(t, unitsUpgrade[i]))
|
|
|
|
|
|
|
+ if(tryBuildStructure(t, unitsUpgrade[i]))
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//remaining tasks
|
|
//remaining tasks
|
|
|
- if (tryBuildNextStructure(t, std::vector<BuildingID>(goldSource, goldSource + ARRAY_COUNT(goldSource))))
|
|
|
|
|
- return;
|
|
|
|
|
- if (tryBuildNextStructure(t, std::vector<BuildingID>(spells, spells + ARRAY_COUNT(spells))))
|
|
|
|
|
|
|
+ if(tryBuildNextStructure(t, std::vector<BuildingID>(spells, spells + ARRAY_COUNT(spells))))
|
|
|
return;
|
|
return;
|
|
|
- if (tryBuildAnyStructure(t, std::vector<BuildingID>(extra, extra + ARRAY_COUNT(extra))))
|
|
|
|
|
|
|
+ if(tryBuildAnyStructure(t, std::vector<BuildingID>(extra, extra + ARRAY_COUNT(extra))))
|
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
//at the end, try to get and build any extra buildings with nonstandard slots (for example HotA 3rd level dwelling)
|
|
//at the end, try to get and build any extra buildings with nonstandard slots (for example HotA 3rd level dwelling)
|
|
|
std::vector<BuildingID> extraBuildings;
|
|
std::vector<BuildingID> extraBuildings;
|
|
|
|
|
|
|
|
- for (auto buildingInfo : t->town->buildings)
|
|
|
|
|
- if (buildingInfo.first > 43)
|
|
|
|
|
|
|
+ for(auto buildingInfo : t->town->buildings)
|
|
|
|
|
+ if(buildingInfo.first > 43)
|
|
|
extraBuildings.push_back(buildingInfo.first);
|
|
extraBuildings.push_back(buildingInfo.first);
|
|
|
|
|
|
|
|
- if (tryBuildAnyStructure(t, extraBuildings))
|
|
|
|
|
|
|
+ if(tryBuildAnyStructure(t, extraBuildings))
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2865,7 +2875,13 @@ void VCAI::validateObject(ObjectIdRef obj)
|
|
|
TResources VCAI::freeResources() const
|
|
TResources VCAI::freeResources() const
|
|
|
{
|
|
{
|
|
|
TResources myRes = cb->getResourceAmount();
|
|
TResources myRes = cb->getResourceAmount();
|
|
|
- myRes[Res::GOLD] -= GOLD_RESERVE;
|
|
|
|
|
|
|
+ auto iterator = cb->getTownsInfo();
|
|
|
|
|
+ if(std::none_of(iterator.begin(), iterator.end(), [](const CGTownInstance * x)->bool
|
|
|
|
|
+ {
|
|
|
|
|
+ return x->builtBuildings.find(BuildingID::CAPITOL) != x->builtBuildings.end();
|
|
|
|
|
+ })
|
|
|
|
|
+ /*|| std::all_of(iterator.begin(), iterator.end(), [](const CGTownInstance * x) -> bool { return x->forbiddenBuildings.find(BuildingID::CAPITOL) != x->forbiddenBuildings.end(); })*/ )
|
|
|
|
|
+ myRes[Res::GOLD] -= GOLD_RESERVE; //what if capitol is blocked from building in all possessed towns (set in map editor)? What about reserve for city hall or something similar in that case?
|
|
|
vstd::amax(myRes[Res::GOLD], 0);
|
|
vstd::amax(myRes[Res::GOLD], 0);
|
|
|
return myRes;
|
|
return myRes;
|
|
|
}
|
|
}
|