From 0793ce2c4ab9c4eaac56c10018b61cb39aef899f Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Tue, 6 Mar 2012 18:49:23 +0000 Subject: [PATCH] AI will now always pick best stacks from towns. It will also crash when picking stacks from objects, work in progress. --- AI/VCAI/VCAI.cpp | 69 ++++++++++++++++++++++++++++++++++++--------- AI/VCAI/VCAI.h | 1 + lib/GameConstants.h | 1 + 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index f8395b7bc..cfda09a6b 100644 --- a/AI/VCAI/VCAI.cpp +++ b/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,22 +894,62 @@ 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(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); + } + } + } } void VCAI::recruitCreatures(const CGDwelling * d) @@ -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 &tiles, std::vector &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 > &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(obj) || dynamic_cast(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()), diff --git a/AI/VCAI/VCAI.h b/AI/VCAI/VCAI.h index 5885f709f..90f81c629 100644 --- a/AI/VCAI/VCAI.h +++ b/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); diff --git a/lib/GameConstants.h b/lib/GameConstants.h index 16f4bc3a6..2053f98d2 100644 --- a/lib/GameConstants.h +++ b/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,