Przeglądaj źródła

Fix possible crash on accessing Cannon Yard from HotA

(cherry picked from commit e273263334ef8900c8fee8e0ae04959ec10b6073)
Ivan Savenko 7 miesięcy temu
rodzic
commit
751a334e5a
2 zmienionych plików z 22 dodań i 3 usunięć
  1. 11 3
      lib/mapObjects/CGDwelling.cpp
  2. 11 0
      server/CGameHandler.cpp

+ 11 - 3
lib/mapObjects/CGDwelling.cpp

@@ -474,9 +474,17 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h) const
 			SetAvailableCreatures sac;
 			sac.tid = id;
 			sac.creatures = creatures;
-			sac.creatures[0].first = !h->getArt(ArtifactPosition::MACH1); //ballista
-			sac.creatures[1].first = !h->getArt(ArtifactPosition::MACH3); //first aid tent
-			sac.creatures[2].first = !h->getArt(ArtifactPosition::MACH2); //ammo cart
+
+			for (auto & entry : sac.creatures)
+			{
+				CreatureID creature = entry.second.at(0);
+				ArtifactID warMachine = creature.toCreature()->warMachine;
+
+				if (h->hasArt(warMachine, true, false))
+					entry.first = 0;
+				else
+					entry.first = 1;
+			}
 			cb->sendAndApply(sac);
 		}
 

+ 11 - 0
server/CGameHandler.cpp

@@ -2397,7 +2397,18 @@ bool CGameHandler::recruitCreatures(ObjectInstanceID objid, ObjectInstanceID dst
 		COMPLAIN_RET_FALSE_IF(!hero, "Only hero can buy war machines");
 		COMPLAIN_RET_FALSE_IF(artId == ArtifactID::CATAPULT, "Catapult cannot be recruited!");
 		COMPLAIN_RET_FALSE_IF(nullptr == art, "Invalid war machine artifact");
+		COMPLAIN_RET_FALSE_IF(hero->hasArt(artId),"Hero already has this machine!");
 
+		bool hasFreeSlot = false;
+		for(auto slot : art->getPossibleSlots().at(ArtBearer::HERO))
+			if (hero->getArt(slot) == nullptr)
+				hasFreeSlot = true;
+
+		if (!hasFreeSlot)
+		{
+			auto slot = art->getPossibleSlots().at(ArtBearer::HERO).front();
+			removeArtifact(ArtifactLocation(hero->id, slot));
+		}
 		return giveHeroNewArtifact(hero, artId, ArtifactPosition::FIRST_AVAILABLE);
 	}
 	else