2
0
Эх сурвалжийг харах

AI will now always pick best stacks from towns.

It will also crash when picking stacks from objects, work in progress.
DjWarmonger 13 жил өмнө
parent
commit
0793ce2c4a
3 өөрчлөгдсөн 57 нэмэгдсэн , 14 устгасан
  1. 55 14
      AI/VCAI/VCAI.cpp
  2. 1 0
      AI/VCAI/VCAI.h
  3. 1 0
      lib/GameConstants.h

+ 55 - 14
AI/VCAI/VCAI.cpp

@@ -779,6 +779,7 @@ void VCAI::showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *do
 	NET_EVENT_HANDLER;
 	LOG_ENTRY;
 	status.addQuery();
+	pickBestCreatures (down, up);
 	onEnd();
 }
 
@@ -893,19 +894,59 @@ void VCAI::moveCreaturesToHero(const CGTownInstance * t)
 {
 	if(t->visitingHero)
 	{
-		for(int i = 0; i < GameConstants::ARMY_SIZE; i++)
+		pickBestCreatures (t->visitingHero, t);
+	}
+}
+
+void VCAI::pickBestCreatures(const CArmedInstance * army, const CArmedInstance * source)
+{
+	if (army->stacksCount() == GameConstants::ARMY_SIZE) //try merging our army first
+	{
+		for (int i = 0; i < GameConstants::ARMY_SIZE; ++i)
 		{
-			if(const CStackInstance *s = t->getStackPtr(i))
+			if (const CStackInstance *s = army->getStackPtr(i))
 			{
-				//find d
-				int dstSlot = t->visitingHero->getSlotFor(s->type);
-				if(dstSlot >= 0)
+				for (int j = 0; j < GameConstants::ARMY_SIZE; ++j)
 				{
-					if(t->visitingHero->hasStackAtSlot(dstSlot))
-						cb->mergeStacks(t, t->visitingHero, i, dstSlot);
-					else
-						cb->swapCreatures(t, t->visitingHero, i, dstSlot);
+					if (i != j && army->mergableStacks(std::pair<TSlot, TSlot>(i, j)))
+					{
+						cb->mergeStacks (army, army, j, i);
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	for (int i = 0; i < GameConstants::ARMY_SIZE; ++i)
+	{
+		if(const CStackInstance *s = source->getStackPtr(i))
+		{
+			//find d
+			int dstSlot = army->getSlotFor(s->type);
+			if(dstSlot >= 0)
+			{
+				if (army->hasStackAtSlot(dstSlot))
+					cb->mergeStacks(source, army, i, dstSlot);
+				else 
+					cb->swapCreatures(source, army, i, dstSlot);
+			}
+			else //exchange poorest stack with stronger one
+			{
+				TSlot weakestStack = 0;
+				for (int j = 1; j < GameConstants::ARMY_SIZE; ++j)
+				{
+					const CStackInstance *p = army->getStackPtr(j);
+					const CStackInstance *w = army->getStackPtr(weakestStack);
+					if (p && w)
+					{
+						if (p->getPower() < w->getPower())
+							weakestStack = j;
+					}
 				}
+				if (const CStackInstance *w = army->getStackPtr(weakestStack))
+					if (w->getPower() < s->getPower())
+						cb->swapCreatures(source, army, i, weakestStack);
 			}
 		}
 	}
@@ -1098,7 +1139,6 @@ void VCAI::wander(const CGHeroInstance * h)
 			break;
 		}
 
-		//TODO real solution for moving army
 		if(h->visitedTown)
 		{
 			townVisitsThisWeek[h].push_back(h->visitedTown);
@@ -1332,7 +1372,6 @@ int howManyTilesWillBeDiscovered(int radious, int3 pos, crint3 dir)
 	return howManyTilesWillBeDiscovered(pos + dir, radious);
 }
 
-
 void getVisibleNeighbours(const std::vector<int3> &tiles, std::vector<int3> &out)
 {
 	BOOST_FOREACH(const int3 &tile, tiles)
@@ -1610,7 +1649,6 @@ int3 VCAI::explorationBestNeighbour(int3 hpos, int radius, const CGHeroInstance
 	throw cannotFulfillGoalException("No neighbour will bring new discoveries!");
 }
 
-
 int3 VCAI::explorationNewPoint(int radius, const CGHeroInstance * h, std::vector<std::vector<int3> > &tiles)
 {
 	TimeCheck tc("looking for new exploration point");
@@ -2344,11 +2382,14 @@ bool isWeeklyRevisitable (const CGObjectInstance * obj)
 { //TODO: allow polling of remaining creatures in dwelling
 	if (dynamic_cast<const CGVisitableOPW *>(obj) || dynamic_cast<const CGDwelling *>(obj)) //ensures future compatibility, unlike IDs
 		return true;
+	switch (obj->ID)
+	{
+		case Obj::STABLES: //any other potential visitable objects?
+			return true;
+	}
 	return false;
 }
 
-
-
 int3 SectorMap::firstTileToGet(const CGHeroInstance *h, crint3 dst)
 {
 	int sourceSector = retreiveTile(h->visitablePos()),

+ 1 - 0
AI/VCAI/VCAI.h

@@ -255,6 +255,7 @@ public:
 	void buildStructure(const CGTownInstance * t);
 	//void recruitCreatures(const CGTownInstance * t);
 	void recruitCreatures(const CGDwelling * d);
+	void pickBestCreatures(const CArmedInstance * army, const CArmedInstance * source); //called when we can't find a slot for new stack
 	void moveCreaturesToHero(const CGTownInstance * t);
 	bool goVisitObj(const CGObjectInstance * obj, const CGHeroInstance * h);
 	void performObjectInteraction(const CGObjectInstance * obj, const CGHeroInstance * h);

+ 1 - 0
lib/GameConstants.h

@@ -188,6 +188,7 @@ namespace Obj
 		PYRAMID = 63,
 		CRYPT = 84,
 		SHIPWRECK = 85,
+		STABLES = 94,
 		TRADING_POST = 99,
 		SUBTERRANEAN_GATE = 103,
 		WHIRLPOOL = 111,