diff --git a/AI/VCAI/BuildingManager.cpp b/AI/VCAI/BuildingManager.cpp index 31c6932e3..cfe0dfc2c 100644 --- a/AI/VCAI/BuildingManager.cpp +++ b/AI/VCAI/BuildingManager.cpp @@ -105,8 +105,13 @@ boost::optional BuildingManager::canBuildAnyStructure(const CGTownIn { if (t->hasBuilt(building)) continue; - if (cb->canBuildStructure(t, building)) - return boost::optional(building); + switch (cb->canBuildStructure(t, building)) + { + case EBuildingState::ALLOWED: + case EBuildingState::NO_RESOURCES: //TODO: allow this via optional parameter? + return boost::optional(building); + break; + } } return boost::optional(); //Can't build anything } diff --git a/AI/VCAI/Goals.cpp b/AI/VCAI/Goals.cpp index 2e0476c85..8c7603ecb 100644 --- a/AI/VCAI/Goals.cpp +++ b/AI/VCAI/Goals.cpp @@ -1052,12 +1052,17 @@ TSubgoal BuildThis::whatToDoToAchieve() } if (town) //we have specific town to build this { - if (cb->canBuildStructure(town, b) != EBuildingState::ALLOWED) //FIXME: decompose further? kind of mess if we're here - throw cannotFulfillGoalException("Not possible to build"); - else + switch (cb->canBuildStructure(town, b)) { - auto res = town->town->buildings.at(BuildingID(bid))->resources; - return ah->whatToDo(res, iAmElementar()); //realize immediately or gather resources + case EBuildingState::ALLOWED: + case EBuildingState::NO_RESOURCES: + { + auto res = town->town->buildings.at(BuildingID(bid))->resources; + return ah->whatToDo(res, iAmElementar()); //realize immediately or gather resources + } + break; + default: + throw cannotFulfillGoalException("Not possible to build"); } } else @@ -1227,7 +1232,7 @@ TSubgoal Goals::CollectRes::whatToDoToTrade() else //either it's our town, or we have hero there { Goals::Trade trade(resID, value, objid); - return sptr(trade.setisElementar(true)); //we can do this immediately - highest priority + return sptr(trade.setisElementar(true)); //we can do this immediately } } } @@ -1454,7 +1459,7 @@ TGoalVec Goals::Build::getAllPossibleSubgoals() } if (ret.empty()) - throw cannotFulfillGoalException("BUILD has been realized as much as possible."); //who catches it and what for? + throw cannotFulfillGoalException("BUILD has been realized as much as possible."); else return ret; } @@ -1522,7 +1527,9 @@ TGoalVec GatherArmy::getAllPossibleSubgoals() } } //build dwelling - auto bid = ah->canBuildAnyStructure(t, std::vector(unitsSource, unitsSource + ARRAY_COUNT(unitsSource)), 8 - cb->getDate(Date::DAY_OF_WEEK)); + //TODO: plan building over multiple turns? + //auto bid = ah->canBuildAnyStructure(t, std::vector(unitsSource, unitsSource + ARRAY_COUNT(unitsSource)), 8 - cb->getDate(Date::DAY_OF_WEEK)); + auto bid = ah->canBuildAnyStructure(t, std::vector(unitsSource, unitsSource + ARRAY_COUNT(unitsSource)), 1); if (bid.is_initialized()) { auto goal = sptr(BuildThis(bid.get(), t).setpriority(priority)); diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index 4da39e808..b13aa1493 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -2121,15 +2121,14 @@ void VCAI::tryRealize(Goals::Trade & g) //trade int toGive, toGet; m->getOffer(res, g.resID, toGive, toGet, EMarketMode::RESOURCE_RESOURCE); - toGive = toGive * (it->resVal / toGive); + toGive = toGive * (it->resVal / toGive); //round down //TODO trade only as much as needed if (toGive) //don't try to sell 0 resources { cb->trade(obj, EMarketMode::RESOURCE_RESOURCE, res, g.resID, toGive); - logAi->debug("Traded %d of %s for %d of %s at %s", toGive, res, toGet, g.resID, obj->getObjectName()); - accquiredResources += toGet; //FIXME: this is incorrect, always equal to 1 + accquiredResources = toGet * (it->resVal / toGive); + logAi->debug("Traded %d of %s for %d of %s at %s", toGive, res, accquiredResources, g.resID, obj->getObjectName()); } - //if (accquiredResources >= g.value) if (ah->freeResources()[g.resID] >= g.value) throw goalFulfilledException(sptr(g)); //we traded all we needed }