1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

Place quest artifacts after all the treasures are already created.

This commit is contained in:
Tomasz Zieliński 2023-04-23 10:08:16 +02:00
parent 1fde8b588b
commit 80b5c53815
11 changed files with 64 additions and 54 deletions

View File

@ -106,6 +106,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/rmg/ObjectDistributor.cpp
${MAIN_LIB_DIR}/rmg/RoadPlacer.cpp
${MAIN_LIB_DIR}/rmg/TreasurePlacer.cpp
${MAIN_LIB_DIR}/rmg/QuestArtifactPlacer.cpp
${MAIN_LIB_DIR}/rmg/RmgMap.cpp
${MAIN_LIB_DIR}/rmg/ConnectionsPlacer.cpp
${MAIN_LIB_DIR}/rmg/WaterAdopter.cpp
@ -371,6 +372,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/rmg/ObjectDistributor.h
${MAIN_LIB_DIR}/rmg/RoadPlacer.h
${MAIN_LIB_DIR}/rmg/TreasurePlacer.h
${MAIN_LIB_DIR}/rmg/QuestArtifactPlacer.h
${MAIN_LIB_DIR}/rmg/RmgMap.h
${MAIN_LIB_DIR}/rmg/ConnectionsPlacer.h
${MAIN_LIB_DIR}/rmg/WaterAdopter.h

View File

@ -37,6 +37,7 @@ CMapGenerator::CMapGenerator(CMapGenOptions& mapGenOptions, int RandomSeed) :
rand.setSeed(this->randomSeed);
mapGenOptions.finalize(rand);
map = std::make_unique<RmgMap>(mapGenOptions);
placer = std::make_shared<CZonePlacer>(*map);
}
int CMapGenerator::getRandomSeed() const
@ -109,6 +110,7 @@ void CMapGenerator::initPrisonsRemaining()
void CMapGenerator::initQuestArtsRemaining()
{
//TODO: Move to QuestArtifactPlacer?
for (auto art : VLC->arth->objects)
{
if (art->aClass == CArtifact::ART_TREASURE && VLC->arth->legalArtifact(art->getId()) && art->constituentOf.empty()) //don't use parts of combined artifacts
@ -267,14 +269,13 @@ void CMapGenerator::addPlayerInfo()
void CMapGenerator::genZones()
{
CZonePlacer placer(*map);
placer.placeZones(&rand);
placer.assignZones(&rand);
placer->placeZones(&rand);
placer->assignZones(&rand);
logGlobal->info("Zones generated successfully");
}
void CMapGenerator::createWaterTreasures()
void CMapGenerator::addWaterTreasuresInfo()
{
if (!getZoneWater())
return;
@ -288,8 +289,7 @@ void CMapGenerator::createWaterTreasures()
void CMapGenerator::fillZones()
{
findZonesForQuestArts();
createWaterTreasures();
addWaterTreasuresInfo();
logGlobal->info("Started filling zones");
@ -331,28 +331,6 @@ void CMapGenerator::fillZones()
Load::Progress::set(250);
}
void CMapGenerator::findZonesForQuestArts()
{
//we want to place arties in zones that were not yet filled (higher index)
for (auto connection : mapGenOptions.getMapTemplate()->getConnections())
{
auto zoneA = map->getZones()[connection.getZoneA()];
auto zoneB = map->getZones()[connection.getZoneB()];
if (zoneA->getId() > zoneB->getId())
{
if(auto * m = zoneB->getModificator<TreasurePlacer>())
m->setQuestArtZone(zoneA.get());
}
else if (zoneA->getId() < zoneB->getId())
{
if(auto * m = zoneA->getModificator<TreasurePlacer>())
m->setQuestArtZone(zoneB.get());
}
}
}
void CMapGenerator::addHeaderInfo()
{
map->map().version = EMapFormat::VCMI;
@ -392,6 +370,11 @@ int CMapGenerator::getPrisonsRemaning() const
return prisonsRemaining;
}
std::shared_ptr<CZonePlacer> CMapGenerator::getZonePlacer() const
{
return placer;
}
void CMapGenerator::decreasePrisonsRemaining()
{
prisonsRemaining = std::max (0, prisonsRemaining - 1);

View File

@ -25,6 +25,7 @@ class JsonNode;
class RmgMap;
class CMap;
class Zone;
class CZonePlacer;
typedef std::vector<JsonNode> JsonVector;
@ -59,16 +60,15 @@ public:
std::unique_ptr<CMap> generate();
void findZonesForQuestArts();
int getNextMonlithIndex();
int getPrisonsRemaning() const;
std::shared_ptr<CZonePlacer> getZonePlacer() const;
void decreasePrisonsRemaining();
const std::vector<ArtifactID> & getQuestArtsRemaning() const;
void banQuestArt(const ArtifactID & id);
Zone * getZoneWater() const;
void createWaterTreasures();
void addWaterTreasuresInfo();
int getRandomSeed() const;
@ -77,6 +77,7 @@ private:
CMapGenOptions& mapGenOptions;
Config config;
std::unique_ptr<RmgMap> map;
std::shared_ptr<CZonePlacer> placer;
std::vector<rmg::ZoneConnection> connectionsLeft;
@ -85,7 +86,7 @@ private:
int prisonsRemaining;
//int questArtsRemaining;
int monolithIndex;
std::vector<ArtifactID> questArtifacts;
std::vector<ArtifactID> questArtifacts; //TODO: Protect with mutex
/// Generation methods
void loadConfig();

View File

@ -869,4 +869,9 @@ void CZonePlacer::assignZones(CRandomGenerator * rand)
logGlobal->info("Finished zone colouring");
}
const TDistanceMap& CZonePlacer::getDistanceMap()
{
return distancesBetweenZones;
}
VCMI_LIB_NAMESPACE_END

View File

@ -26,6 +26,7 @@ typedef std::vector<std::pair<TRmgTemplateZoneId, std::shared_ptr<Zone>>> TZoneV
typedef std::map<TRmgTemplateZoneId, std::shared_ptr<Zone>> TZoneMap;
typedef std::map<std::shared_ptr<Zone>, float3> TForceVector;
typedef std::map<std::shared_ptr<Zone>, float> TDistanceVector;
typedef std::map<int, std::map<int, size_t>> TDistanceMap;
class CZonePlacer
{
@ -40,6 +41,8 @@ public:
void findPathsBetweenZones();
void placeOnGrid(CRandomGenerator* rand);
void assignZones(CRandomGenerator * rand);
const TDistanceMap & getDistanceMap();
private:
void prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const bool underground, CRandomGenerator * rand);
@ -65,7 +68,7 @@ private:
float bestTotalOverlap;
//distance [a][b] = number of zone connections required to travel between the zones
std::map<int, std::map<int, size_t>> distancesBetweenZones;
TDistanceMap distancesBetweenZones;
std::set<TRmgTemplateZoneId> lastSwappedZones;
RmgMap & map;
};

View File

@ -16,6 +16,8 @@
#include "RoadPlacer.h"
#include "RiverPlacer.h"
#include "WaterAdopter.h"
#include "TreasurePlacer.h"
#include "QuestArtifactPlacer.h"
#include "../CCreatureHandler.h"
#include "../mapObjects/CommonConstructors.h"
#include "../mapObjects/MapObjects.h" //needed to resolve templates for CommonConstructors.h
@ -379,6 +381,21 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
m->areaIsolated().add(instance->getVisitablePosition() + int3(0, -1, 0));
}
}
switch (instance->object().ID)
{
case Obj::RANDOM_TREASURE_ART:
case Obj::RANDOM_MINOR_ART: //In OH3 quest artifacts have higher value than normal arts
{
if (auto * qap = zone.getModificator<QuestArtifactPlacer>())
{
qap->rememberPotentialArtifactToReplace(&instance->object());
}
break;
}
default:
break;
}
}
switch(object.instances().front()->object().ID)

View File

@ -19,6 +19,7 @@
#include "ObjectManager.h"
#include "RoadPlacer.h"
#include "TreasurePlacer.h"
#include "QuestArtifactPlacer.h"
#include "ConnectionsPlacer.h"
#include "TownPlacer.h"
#include "MinePlacer.h"
@ -139,6 +140,7 @@ void RmgMap::addModificators()
{
zone->addModificator<TownPlacer>();
zone->addModificator<MinePlacer>();
zone->addModificator<QuestArtifactPlacer>();
zone->addModificator<ConnectionsPlacer>();
zone->addModificator<RoadPlacer>();
zone->addModificator<RiverPlacer>();

View File

@ -17,6 +17,8 @@
#include "ConnectionsPlacer.h"
#include "RmgMap.h"
#include "TileInfo.h"
#include "CZonePlacer.h"
#include "QuestArtifactPlacer.h"
#include "../mapObjects/CommonConstructors.h"
#include "../mapObjects/MapObjects.h" //needed to resolve templates for CommonConstructors.h
#include "../CCreatureHandler.h"
@ -41,11 +43,6 @@ void TreasurePlacer::init()
POSTFUNCTION(RoadPlacer);
}
void TreasurePlacer::setQuestArtZone(Zone * otherZone)
{
questArtZone = otherZone;
}
void TreasurePlacer::addObjectToRandomPool(const ObjectInfo& oi)
{
possibleObjects.push_back(oi);
@ -389,8 +386,8 @@ void TreasurePlacer::addAllPossibleObjects()
addObjectToRandomPool(oi);
//seer huts with creatures or generic rewards
if(questArtZone) //we won't be placing seer huts if there is no zone left to place arties
if(zone.getConnections().size()) //Unlikely, but...
{
static const int genericSeerHuts = 8;
int seerHutsPerType = 0;
@ -450,9 +447,7 @@ void TreasurePlacer::addAllPossibleObjects()
obj->quest->isCustomFirst = obj->quest->isCustomNext = obj->quest->isCustomComplete = false;
generator.banQuestArt(artid);
this->questArtZone->getModificator<TreasurePlacer>()->addObjectToRandomPool(generateArtInfo(artid));
zone.getModificator<QuestArtifactPlacer>()->addQuestArtifact(artid);
return obj;
};
@ -487,8 +482,7 @@ void TreasurePlacer::addAllPossibleObjects()
obj->quest->isCustomFirst = obj->quest->isCustomNext = obj->quest->isCustomComplete = false;
generator.banQuestArt(artid);
this->questArtZone->getModificator<TreasurePlacer>()->addObjectToRandomPool(generateArtInfo(artid));
zone.getModificator<QuestArtifactPlacer>()->addQuestArtifact(artid);
return obj;
};
@ -510,8 +504,7 @@ void TreasurePlacer::addAllPossibleObjects()
obj->quest->isCustomFirst = obj->quest->isCustomNext = obj->quest->isCustomComplete = false;
generator.banQuestArt(artid);
this->questArtZone->getModificator<TreasurePlacer>()->addObjectToRandomPool(generateArtInfo(artid));
zone.getModificator<QuestArtifactPlacer>()->addQuestArtifact(artid);
return obj;
};

View File

@ -1,5 +1,5 @@
/*
* TreasurePlacer.cpp, part of VCMI engine
* TreasurePlacer.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
@ -18,6 +18,7 @@ class CGObjectInstance;
class ObjectManager;
class RmgMap;
class CMapGenerator;
class CRandomGenerator;
struct ObjectInfo
{
@ -43,8 +44,6 @@ public:
char dump(const int3 &) override;
void createTreasures(ObjectManager & manager);
void setQuestArtZone(Zone * otherZone);
void addObjectToRandomPool(const ObjectInfo& oi);
void addAllPossibleObjects(); //add objects, including zone-specific, to possibleObjects
@ -56,8 +55,7 @@ protected:
ObjectInfo * getRandomObject(ui32 desiredValue, ui32 currentValue, ui32 maxValue, bool allowLargeObjects);
std::vector<ObjectInfo*> prepareTreasurePile(const CTreasureInfo & treasureInfo);
rmg::Object constructTreasurePile(const std::vector<ObjectInfo*> & treasureInfos, bool densePlacement = false);
protected:
std::vector<ObjectInfo> possibleObjects;
int minGuardedValue = 0;
@ -65,8 +63,6 @@ protected:
rmg::Area treasureArea;
rmg::Area treasureBlockArea;
rmg::Area guards;
Zone * questArtZone = nullptr; //artifacts required for Seer Huts will be placed here - or not if null
};
VCMI_LIB_NAMESPACE_END

View File

@ -95,6 +95,11 @@ rmg::Area & Zone::areaUsed()
return dAreaUsed;
}
std::vector<int3> Zone::getPossibleQuestArtifactPos() const
{
return possibleQuestArtifactPos;
}
void Zone::clearTiles()
{
dArea.clear();

View File

@ -93,6 +93,8 @@ public:
rmg::Area & areaPossible();
rmg::Area & freePaths();
rmg::Area & areaUsed();
std::vector<int3> getPossibleQuestArtifactPos() const;
void initFreeTiles();
void clearTiles();
@ -137,6 +139,7 @@ protected:
rmg::Area dAreaPossible;
rmg::Area dAreaFree; //core paths of free tiles that all other objects will be linked to
rmg::Area dAreaUsed;
std::vector<int3> possibleQuestArtifactPos;
//template info
si32 townType;