| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 | 
							- /*
 
- * QuestArtifact.cpp, part of VCMI engine
 
- *
 
- * Authors: listed in file AUTHORS in main folder
 
- *
 
- * License: GNU General Public License v2.0 or later
 
- * Full text of license available in license.txt file, in main folder
 
- *
 
- */
 
- #include "StdInc.h"
 
- #include "QuestArtifactPlacer.h"
 
- #include "../CMapGenerator.h"
 
- #include "../RmgMap.h"
 
- #include "TreasurePlacer.h"
 
- #include "../CZonePlacer.h"
 
- #include "../../VCMI_Lib.h"
 
- #include "../../mapObjectConstructors/AObjectTypeHandler.h"
 
- #include "../../mapObjectConstructors/CObjectClassesHandler.h"
 
- #include "../../mapObjects/MapObjects.h" 
 
- VCMI_LIB_NAMESPACE_BEGIN
 
- void QuestArtifactPlacer::process()
 
- {
 
- 	findZonesForQuestArts();
 
- 	placeQuestArtifacts(zone.getRand());
 
- }
 
- void QuestArtifactPlacer::init()
 
- {
 
- 	DEPENDENCY_ALL(TreasurePlacer);
 
- }
 
- void QuestArtifactPlacer::addQuestArtZone(std::shared_ptr<Zone> otherZone)
 
- {
 
- 	RecursiveLock lock(externalAccessMutex);
 
- 	questArtZones.push_back(otherZone);
 
- }
 
- void QuestArtifactPlacer::addQuestArtifact(const ArtifactID& id)
 
- {
 
- 	logGlobal->trace("Need to place quest artifact %s", VLC->artifacts()->getById(id)->getNameTranslated());
 
- 	RecursiveLock lock(externalAccessMutex);
 
- 	questArtifactsToPlace.emplace_back(id);
 
- }
 
- void QuestArtifactPlacer::removeQuestArtifact(const ArtifactID& id)
 
- {
 
- 	logGlobal->trace("Will not try to place quest artifact %s", VLC->artifacts()->getById(id)->getNameTranslated());
 
- 	RecursiveLock lock(externalAccessMutex);
 
- 	vstd::erase_if_present(questArtifactsToPlace, id);
 
- }
 
- void QuestArtifactPlacer::rememberPotentialArtifactToReplace(CGObjectInstance* obj)
 
- {
 
- 	RecursiveLock lock(externalAccessMutex);
 
- 	artifactsToReplace.push_back(obj);
 
- }
 
- std::vector<CGObjectInstance*> QuestArtifactPlacer::getPossibleArtifactsToReplace() const
 
- {
 
- 	RecursiveLock lock(externalAccessMutex);
 
- 	return artifactsToReplace;
 
- }
 
- void QuestArtifactPlacer::findZonesForQuestArts()
 
- {
 
- 	const auto& distances = generator.getZonePlacer()->getDistanceMap().at(zone.getId());
 
- 	for (auto const& connectedZone : distances)
 
- 	{
 
- 		// Choose zones that are 1 or 2 connections away
 
- 		if (vstd::iswithin(connectedZone.second, 1, 2))
 
- 		{
 
- 			addQuestArtZone(map.getZones().at(connectedZone.first));
 
- 		}
 
- 	}
 
- 	logGlobal->trace("Number of nearby zones suitable for quest artifacts: %d", questArtZones.size());
 
- }
 
- void QuestArtifactPlacer::placeQuestArtifacts(CRandomGenerator & rand)
 
- {
 
- 	for (const auto & artifactToPlace : questArtifactsToPlace)
 
- 	{
 
- 		RandomGeneratorUtil::randomShuffle(questArtZones, rand);
 
- 		for (auto zone : questArtZones)
 
- 		{
 
- 			auto* qap = zone->getModificator<QuestArtifactPlacer>();
 
- 			std::vector<CGObjectInstance *> artifactsToReplace = qap->getPossibleArtifactsToReplace();
 
- 			if (artifactsToReplace.empty())
 
- 				continue;
 
- 			auto artifactToReplace = *RandomGeneratorUtil::nextItem(artifactsToReplace, rand);
 
- 			logGlobal->trace("Replacing %s at %s with the quest artifact %s",
 
- 				artifactToReplace->getObjectName(),
 
- 				artifactToReplace->getPosition().toString(),
 
- 				VLC->artifacts()->getById(artifactToPlace)->getNameTranslated());
 
- 			//Update appearance. Terrain is irrelevant.
 
- 			auto handler = VLC->objtypeh->getHandlerFor(Obj::ARTIFACT, artifactToPlace);
 
- 			auto newObj = handler->create(map.mapInstance->cb, nullptr);
 
- 			auto templates = handler->getTemplates();
 
- 			//artifactToReplace->appearance = templates.front();
 
- 			newObj->appearance  = templates.front();
 
- 			newObj->pos = artifactToReplace->pos;
 
- 			mapProxy->insertObject(newObj);
 
- 			for (auto z : map.getZones())
 
- 			{
 
- 				//Every qap has its OWN collection of artifacts
 
- 				auto * localQap = zone->getModificator<QuestArtifactPlacer>();
 
- 				if (localQap)
 
- 				{
 
- 					localQap->dropReplacedArtifact(artifactToReplace);
 
- 				}
 
- 			}
 
- 			mapProxy->removeObject(artifactToReplace);
 
- 			break;
 
- 		}
 
- 	}
 
- }
 
- void QuestArtifactPlacer::dropReplacedArtifact(CGObjectInstance* obj)
 
- {
 
- 	RecursiveLock lock(externalAccessMutex);
 
- 	boost::remove(artifactsToReplace, obj);
 
- }
 
- size_t QuestArtifactPlacer::getMaxQuestArtifactCount() const
 
- {
 
- 	RecursiveLock lock(externalAccessMutex);
 
- 	return questArtifacts.size();
 
- }
 
- ArtifactID QuestArtifactPlacer::drawRandomArtifact()
 
- {
 
- 	RecursiveLock lock(externalAccessMutex);
 
- 	if (!questArtifacts.empty())
 
- 	{
 
- 		RandomGeneratorUtil::randomShuffle(questArtifacts, zone.getRand());
 
- 		ArtifactID ret = questArtifacts.back();
 
- 		questArtifacts.pop_back();
 
- 		generator.banQuestArt(ret);
 
- 		return ret;
 
- 	}
 
- 	else
 
- 	{
 
- 		throw rmgException("No quest artifacts left for this zone!");
 
- 	}
 
- }
 
- void QuestArtifactPlacer::addRandomArtifact(const ArtifactID & artid)
 
- {
 
- 	RecursiveLock lock(externalAccessMutex);
 
- 	questArtifacts.push_back(artid);
 
- 	generator.unbanQuestArt(artid);
 
- }
 
- VCMI_LIB_NAMESPACE_END
 
 
  |