Przeglądaj źródła

Merge pull request #481 from vcmi/VCAI_fixes

Vcai fixes
DjWarmonger 7 lat temu
rodzic
commit
2b6bb0f4c6
4 zmienionych plików z 28 dodań i 19 usunięć
  1. 7 2
      AI/VCAI/BuildingManager.cpp
  2. 17 12
      AI/VCAI/Goals.cpp
  3. 1 1
      AI/VCAI/Goals.h
  4. 3 4
      AI/VCAI/VCAI.cpp

+ 7 - 2
AI/VCAI/BuildingManager.cpp

@@ -105,8 +105,13 @@ boost::optional<BuildingID> BuildingManager::canBuildAnyStructure(const CGTownIn
 	{
 		if (t->hasBuilt(building))
 			continue;
-		if (cb->canBuildStructure(t, building))
-			return boost::optional<BuildingID>(building);
+		switch (cb->canBuildStructure(t, building))
+		{
+			case EBuildingState::ALLOWED:
+			case EBuildingState::NO_RESOURCES: //TODO: allow this via optional parameter?
+				return boost::optional<BuildingID>(building);
+				break;
+		}
 	}
 	return boost::optional<BuildingID>(); //Can't build anything
 }

+ 17 - 12
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
@@ -1137,11 +1142,9 @@ TGoalVec Goals::CollectRes::getAllPossibleSubgoals()
 		}
 		for (auto obj : ourObjs)
 		{
-			if (ai->isAccessibleForHero(obj->visitablePos(), h))
-			{
-				//further decomposition and evaluation will be handled by VisitObj
+			auto pos = obj->visitablePos();	
+			if (ai->isTileNotReserved(h, pos)) //further decomposition and evaluation will be handled by VisitObj
 				ret.push_back(sptr(Goals::VisitObj(obj->id.getNum()).sethero(h).setisAbstract(true)));
-			}
 		}
 	}
 	return ret;
@@ -1227,7 +1230,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 +1457,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 +1525,9 @@ TGoalVec GatherArmy::getAllPossibleSubgoals()
 				}
 			}
 			//build dwelling
-			auto bid = ah->canBuildAnyStructure(t, std::vector<BuildingID>(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<BuildingID>(unitsSource, unitsSource + ARRAY_COUNT(unitsSource)), 8 - cb->getDate(Date::DAY_OF_WEEK));
+			auto bid = ah->canBuildAnyStructure(t, std::vector<BuildingID>(unitsSource, unitsSource + ARRAY_COUNT(unitsSource)), 1);
 			if (bid.is_initialized())
 			{
 				auto goal = sptr(BuildThis(bid.get(), t).setpriority(priority));

+ 1 - 1
AI/VCAI/Goals.h

@@ -432,7 +432,7 @@ public:
 		resID = rid;
 		value = val;
 		objid = Objid;
-		priority = 10; //do it immediately
+		priority = 3; //trading is instant, but picking resources is free
 	}
 	TSubgoal whatToDoToAchieve() override;
 	bool operator==(AbstractGoal & g) override;

+ 3 - 4
AI/VCAI/VCAI.cpp

@@ -2123,15 +2123,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
 			}