Browse Source

Restored artifact selection & exchange, work in progress.

DjWarmonger 10 years ago
parent
commit
b3f482b8a8
4 changed files with 86 additions and 5 deletions
  1. 11 0
      AI/VCAI/AIUtility.cpp
  2. 1 0
      AI/VCAI/AIUtility.h
  3. 73 5
      AI/VCAI/VCAI.cpp
  4. 1 0
      AI/VCAI/VCAI.h

+ 11 - 0
AI/VCAI/AIUtility.cpp

@@ -499,3 +499,14 @@ bool compareArmyStrength(const CArmedInstance *a1, const CArmedInstance *a2)
 {
 	return a1->getArmyStrength() < a2->getArmyStrength();
 }
+
+bool compareArtifacts(const CArtifactInstance *a1, const CArtifactInstance *a2)
+{
+	auto art1 = a1->artType;
+	auto art2 = a2->artType;
+
+	if (art1->valOfBonuses(Bonus::PRIMARY_SKILL) > art2->valOfBonuses(Bonus::PRIMARY_SKILL))
+		return true;
+	else
+		return art1->price > art2->price;
+}

+ 1 - 0
AI/VCAI/AIUtility.h

@@ -158,6 +158,7 @@ bool boundaryBetweenTwoPoints (int3 pos1, int3 pos2, CCallback * cbp);
 bool compareMovement(HeroPtr lhs, HeroPtr rhs);
 bool compareHeroStrength(HeroPtr h1, HeroPtr h2);
 bool compareArmyStrength(const CArmedInstance *a1, const CArmedInstance *a2);
+bool compareArtifacts(const CArtifactInstance *a1, const CArtifactInstance *a2);
 ui64 howManyReinforcementsCanGet(HeroPtr h, const CGTownInstance *t);
 int3 whereToExplore(HeroPtr h);
 

+ 73 - 5
AI/VCAI/VCAI.cpp

@@ -320,21 +320,26 @@ void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, Q
 		if (secondGoal->goalType == Goals::GATHER_ARMY)
 			goalpriority2 = secondGoal->priority;
 
+		auto transferFrom2to1 = [this](const CGHeroInstance * h1, const CGHeroInstance *h2) -> void
+		{
+			this->pickBestCreatures(h1, h2);
+			this->pickBestArtifacts(h1, h2);
+		};
+
 		if (goalpriority1 > goalpriority2)
-			pickBestCreatures (firstHero, secondHero);
+			transferFrom2to1 (firstHero, secondHero);
 		else if (goalpriority1 < goalpriority2)
-			pickBestCreatures (secondHero, firstHero);
+			transferFrom2to1 (secondHero, firstHero);
 		else //regular criteria
 		{
 			if (firstHero->getFightingStrength() > secondHero->getFightingStrength() && canGetArmy(firstHero, secondHero))
-				pickBestCreatures(firstHero, secondHero);
+				transferFrom2to1 (firstHero, secondHero);
 			else if (canGetArmy(secondHero, firstHero))
-				pickBestCreatures(secondHero, firstHero);
+				transferFrom2to1 (secondHero, firstHero);
 		}
 
 		completeGoal(sptr(Goals::VisitHero(firstHero->id.getNum()))); //TODO: what if we were visited by other hero in the meantime?
 		completeGoal(sptr(Goals::VisitHero(secondHero->id.getNum())));
-		//TODO: exchange artifacts
 
 		answerQuery(query, 0);
 	});
@@ -982,6 +987,68 @@ void VCAI::pickBestCreatures(const CArmedInstance * army, const CArmedInstance *
 	}
 }
 
+void VCAI::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance * other)
+{
+	std::vector<ArtifactLocation> allArtifacts;
+
+	for (auto p : h->artifactsWorn)
+	{
+		if (p.second.artifact)
+			allArtifacts.push_back(ArtifactLocation(h, p.first));
+	}
+	for (auto slot : h->artifactsInBackpack)
+		allArtifacts.push_back(ArtifactLocation(h, h->getArtPos(slot.artifact)));
+
+	if (other)
+	{
+		for (auto p : other->artifactsWorn)
+		{
+			if (p.second.artifact)
+				allArtifacts.push_back(ArtifactLocation(other, p.first));
+		}
+		for (auto slot : other->artifactsInBackpack)
+			allArtifacts.push_back(ArtifactLocation(other, other->getArtPos(slot.artifact)));
+	}
+	
+
+	for (auto location : allArtifacts)
+	{
+		auto artifact = location.getSlot()->artifact;
+		auto otherSlot = h->getSlot(artifact->firstAvailableSlot(h));
+		if (otherSlot && otherSlot->artifact)
+			if (compareArtifacts (artifact, otherSlot->artifact)) //if that artifact is better than what we have, pick it
+				cb->swapArtifacts (location, ArtifactLocation(h, h->getArtPos(otherSlot->artifact)));
+	}
+
+	if (other)
+	{
+		//do not touch artifacts worn by first (main) hero
+		//slots may have moved significantly, just start from scratch
+		allArtifacts.clear();
+
+		for (auto slot : h->artifactsInBackpack)
+			allArtifacts.push_back(ArtifactLocation(h, h->getArtPos(slot.artifact)));
+
+		for (auto p : other->artifactsWorn)
+		{
+			if (p.second.artifact)
+				allArtifacts.push_back(ArtifactLocation(other, p.first));
+		}
+		for (auto slot : other->artifactsInBackpack)
+			allArtifacts.push_back(ArtifactLocation(other, other->getArtPos(slot.artifact)));
+
+		for (auto location : allArtifacts)
+		{
+			auto artifact = location.getSlot()->artifact;
+			auto otherSlot = other->getSlot(artifact->firstAvailableSlot(other));
+			if (otherSlot && otherSlot->artifact)
+				if (compareArtifacts(artifact, otherSlot->artifact)) //if that artifact is better than what we have, pick it
+					cb->swapArtifacts(location, ArtifactLocation(other, other->getArtPos(otherSlot->artifact)));
+		}
+	}
+
+}
+
 void VCAI::recruitCreatures(const CGDwelling * d, const CArmedInstance * recruiter)
 {
 	for(int i = 0; i < d->creatures.size(); i++)
@@ -2315,6 +2382,7 @@ void VCAI::performTypicalActions()
 	{
         logAi->debugStream() << boost::format("Looking into %s, MP=%d") % h->name.c_str() % h->movement;
 		makePossibleUpgrades(*h);
+		pickBestArtifacts(*h);
 		try
 		{
 			wander(h);

+ 1 - 0
AI/VCAI/VCAI.h

@@ -274,6 +274,7 @@ public:
 	void recruitCreatures(const CGDwelling * d, const CArmedInstance * recruiter);
 	bool canGetArmy (const CGHeroInstance * h, const CGHeroInstance * source); //can we get any better stacks from other hero?
 	void pickBestCreatures(const CArmedInstance * army, const CArmedInstance * source); //called when we can't find a slot for new stack
+	void pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance * other = nullptr);
 	void moveCreaturesToHero(const CGTownInstance * t);
 	bool goVisitObj(const CGObjectInstance * obj, HeroPtr h);
 	void performObjectInteraction(const CGObjectInstance * obj, HeroPtr h);