Explorar el Código

AI will now always pick best stacks from towns.

It will also crash when picking stacks from objects, work in progress.
DjWarmonger hace 13 años
padre
commit
0793ce2c4a
Se han modificado 3 ficheros con 57 adiciones y 14 borrados
  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,