|
|
@@ -0,0 +1,110 @@
|
|
|
+/*
|
|
|
+* 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 "../mapObjects/CObjectHandler.h"
|
|
|
+#include "../mapObjects/CommonConstructors.h"
|
|
|
+#include "../mapObjects/MapObjects.h"
|
|
|
+
|
|
|
+void QuestArtifactPlacer::process()
|
|
|
+{
|
|
|
+ findZonesForQuestArts();
|
|
|
+ placeQuestArtifacts(&generator.rand);
|
|
|
+}
|
|
|
+
|
|
|
+void QuestArtifactPlacer::init()
|
|
|
+{
|
|
|
+ DEPENDENCY_ALL(TreasurePlacer);
|
|
|
+}
|
|
|
+
|
|
|
+void QuestArtifactPlacer::addQuestArtZone(std::shared_ptr<Zone> otherZone)
|
|
|
+{
|
|
|
+ questArtZones.push_back(otherZone);
|
|
|
+}
|
|
|
+
|
|
|
+void QuestArtifactPlacer::addQuestArtifact(const ArtifactID& id)
|
|
|
+{
|
|
|
+ logGlobal->info((boost::format("Need to place quest artifact artifact %s")
|
|
|
+ % VLC->arth->getById(id)->getNameTranslated()).str());
|
|
|
+ questArtifactsToPlace.emplace_back(id);
|
|
|
+}
|
|
|
+
|
|
|
+void QuestArtifactPlacer::rememberPotentialArtifactToReplace(CGObjectInstance* obj)
|
|
|
+{
|
|
|
+ artifactsToReplace.push_back(obj);
|
|
|
+}
|
|
|
+
|
|
|
+std::vector<CGObjectInstance*> QuestArtifactPlacer::getPossibleArtifactsToReplace() const
|
|
|
+{
|
|
|
+ return artifactsToReplace;
|
|
|
+}
|
|
|
+
|
|
|
+void QuestArtifactPlacer::findZonesForQuestArts()
|
|
|
+{
|
|
|
+ //FIXME: Store and access CZonePlacer from CMapGenerator
|
|
|
+
|
|
|
+ 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->info((boost::format("Number of nearby zones suitable for quest artifacts: %d") % questArtZones.size()).str());
|
|
|
+ logGlobal->info((boost::format("Number of possible quest artifacts remaining: %d") % generator.getQuestArtsRemaning().size()).str());
|
|
|
+}
|
|
|
+
|
|
|
+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->info((boost::format("Replacing %s at %s with the quest artifact %s")
|
|
|
+ % artifactToReplace->getObjectName()
|
|
|
+ % artifactToReplace->getPosition().toString()
|
|
|
+ % VLC->arth->getById(artifactToPlace)->getNameTranslated()).str());
|
|
|
+ artifactToReplace->ID = Obj::ARTIFACT;
|
|
|
+ artifactToReplace->subID = artifactToPlace;
|
|
|
+
|
|
|
+ //Update appearance. Terrain is irrelevant.
|
|
|
+ auto handler = VLC->objtypeh->getHandlerFor(Obj::ARTIFACT, artifactToPlace);
|
|
|
+ auto templates = handler->getTemplates();
|
|
|
+ artifactToReplace->appearance = templates.front();
|
|
|
+ //FIXME: Instance name is still "randomArtifact"
|
|
|
+
|
|
|
+ qap->dropReplacedArtifact(artifactToReplace);
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void QuestArtifactPlacer::dropReplacedArtifact(CGObjectInstance* obj)
|
|
|
+{
|
|
|
+ boost::remove(artifactsToReplace, obj);
|
|
|
+}
|