Преглед изворни кода

AI will now always pick best stacks from towns.

It will also crash when picking stacks from objects, work in progress.
DjWarmonger пре 13 година
родитељ
комит
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;
 	NET_EVENT_HANDLER;
 	LOG_ENTRY;
 	LOG_ENTRY;
 	status.addQuery();
 	status.addQuery();
+	pickBestCreatures (down, up);
 	onEnd();
 	onEnd();
 }
 }
 
 
@@ -893,19 +894,59 @@ void VCAI::moveCreaturesToHero(const CGTownInstance * t)
 {
 {
 	if(t->visitingHero)
 	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;
 			break;
 		}
 		}
 
 
-		//TODO real solution for moving army
 		if(h->visitedTown)
 		if(h->visitedTown)
 		{
 		{
 			townVisitsThisWeek[h].push_back(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);
 	return howManyTilesWillBeDiscovered(pos + dir, radious);
 }
 }
 
 
-
 void getVisibleNeighbours(const std::vector<int3> &tiles, std::vector<int3> &out)
 void getVisibleNeighbours(const std::vector<int3> &tiles, std::vector<int3> &out)
 {
 {
 	BOOST_FOREACH(const int3 &tile, tiles)
 	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!");
 	throw cannotFulfillGoalException("No neighbour will bring new discoveries!");
 }
 }
 
 
-
 int3 VCAI::explorationNewPoint(int radius, const CGHeroInstance * h, std::vector<std::vector<int3> > &tiles)
 int3 VCAI::explorationNewPoint(int radius, const CGHeroInstance * h, std::vector<std::vector<int3> > &tiles)
 {
 {
 	TimeCheck tc("looking for new exploration point");
 	TimeCheck tc("looking for new exploration point");
@@ -2344,11 +2382,14 @@ bool isWeeklyRevisitable (const CGObjectInstance * obj)
 { //TODO: allow polling of remaining creatures in dwelling
 { //TODO: allow polling of remaining creatures in dwelling
 	if (dynamic_cast<const CGVisitableOPW *>(obj) || dynamic_cast<const CGDwelling *>(obj)) //ensures future compatibility, unlike IDs
 	if (dynamic_cast<const CGVisitableOPW *>(obj) || dynamic_cast<const CGDwelling *>(obj)) //ensures future compatibility, unlike IDs
 		return true;
 		return true;
+	switch (obj->ID)
+	{
+		case Obj::STABLES: //any other potential visitable objects?
+			return true;
+	}
 	return false;
 	return false;
 }
 }
 
 
-
-
 int3 SectorMap::firstTileToGet(const CGHeroInstance *h, crint3 dst)
 int3 SectorMap::firstTileToGet(const CGHeroInstance *h, crint3 dst)
 {
 {
 	int sourceSector = retreiveTile(h->visitablePos()),
 	int sourceSector = retreiveTile(h->visitablePos()),

+ 1 - 0
AI/VCAI/VCAI.h

@@ -255,6 +255,7 @@ public:
 	void buildStructure(const CGTownInstance * t);
 	void buildStructure(const CGTownInstance * t);
 	//void recruitCreatures(const CGTownInstance * t);
 	//void recruitCreatures(const CGTownInstance * t);
 	void recruitCreatures(const CGDwelling * d);
 	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);
 	void moveCreaturesToHero(const CGTownInstance * t);
 	bool goVisitObj(const CGObjectInstance * obj, const CGHeroInstance * h);
 	bool goVisitObj(const CGObjectInstance * obj, const CGHeroInstance * h);
 	void performObjectInteraction(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,
 		PYRAMID = 63,
 		CRYPT = 84,
 		CRYPT = 84,
 		SHIPWRECK = 85,
 		SHIPWRECK = 85,
+		STABLES = 94,
 		TRADING_POST = 99,
 		TRADING_POST = 99,
 		SUBTERRANEAN_GATE = 103,
 		SUBTERRANEAN_GATE = 103,
 		WHIRLPOOL = 111,
 		WHIRLPOOL = 111,