mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-04 23:17:41 +02:00
Give every Zone its own RNG
This commit is contained in:
parent
5da8c96214
commit
15b254fded
@ -127,7 +127,7 @@ std::unique_ptr<CMap> CMapGenerator::generate()
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
addHeaderInfo();
|
addHeaderInfo();
|
||||||
map->initTiles(*this);
|
map->initTiles(*this, rand);
|
||||||
Load::Progress::step();
|
Load::Progress::step();
|
||||||
initPrisonsRemaining();
|
initPrisonsRemaining();
|
||||||
initQuestArtsRemaining();
|
initQuestArtsRemaining();
|
||||||
|
@ -54,8 +54,6 @@ public:
|
|||||||
|
|
||||||
const Config & getConfig() const;
|
const Config & getConfig() const;
|
||||||
|
|
||||||
CRandomGenerator rand;
|
|
||||||
|
|
||||||
const CMapGenOptions& getMapGenOptions() const;
|
const CMapGenOptions& getMapGenOptions() const;
|
||||||
|
|
||||||
std::unique_ptr<CMap> generate();
|
std::unique_ptr<CMap> generate();
|
||||||
@ -74,6 +72,7 @@ public:
|
|||||||
int getRandomSeed() const;
|
int getRandomSeed() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
CRandomGenerator rand;
|
||||||
int randomSeed;
|
int randomSeed;
|
||||||
CMapGenOptions& mapGenOptions;
|
CMapGenOptions& mapGenOptions;
|
||||||
Config config;
|
Config config;
|
||||||
|
@ -77,7 +77,7 @@ void RmgMap::foreachDiagonalNeighbour(const int3 & pos, const std::function<void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RmgMap::initTiles(CMapGenerator & generator)
|
void RmgMap::initTiles(CMapGenerator & generator, CRandomGenerator & rand)
|
||||||
{
|
{
|
||||||
mapInstance->initTerrain();
|
mapInstance->initTerrain();
|
||||||
|
|
||||||
@ -88,15 +88,15 @@ void RmgMap::initTiles(CMapGenerator & generator)
|
|||||||
for (auto faction : VLC->townh->getAllowedFactions())
|
for (auto faction : VLC->townh->getAllowedFactions())
|
||||||
zonesPerFaction[faction] = 0;
|
zonesPerFaction[faction] = 0;
|
||||||
|
|
||||||
getEditManager()->clearTerrain(&generator.rand);
|
getEditManager()->clearTerrain(&rand);
|
||||||
getEditManager()->getTerrainSelection().selectRange(MapRect(int3(0, 0, 0), mapGenOptions.getWidth(), mapGenOptions.getHeight()));
|
getEditManager()->getTerrainSelection().selectRange(MapRect(int3(0, 0, 0), mapGenOptions.getWidth(), mapGenOptions.getHeight()));
|
||||||
getEditManager()->drawTerrain(ETerrainId::GRASS, &generator.rand);
|
getEditManager()->drawTerrain(ETerrainId::GRASS, &rand);
|
||||||
|
|
||||||
const auto * tmpl = mapGenOptions.getMapTemplate();
|
const auto * tmpl = mapGenOptions.getMapTemplate();
|
||||||
zones.clear();
|
zones.clear();
|
||||||
for(const auto & option : tmpl->getZones())
|
for(const auto & option : tmpl->getZones())
|
||||||
{
|
{
|
||||||
auto zone = std::make_shared<Zone>(*this, generator);
|
auto zone = std::make_shared<Zone>(*this, generator, rand);
|
||||||
zone->setOptions(*option.second);
|
zone->setOptions(*option.second);
|
||||||
zones[zone->getId()] = zone;
|
zones[zone->getId()] = zone;
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ void RmgMap::initTiles(CMapGenerator & generator)
|
|||||||
rmg::ZoneOptions options;
|
rmg::ZoneOptions options;
|
||||||
options.setId(waterId);
|
options.setId(waterId);
|
||||||
options.setType(ETemplateZoneType::WATER);
|
options.setType(ETemplateZoneType::WATER);
|
||||||
auto zone = std::make_shared<Zone>(*this, generator);
|
auto zone = std::make_shared<Zone>(*this, generator, rand);
|
||||||
zone->setOptions(options);
|
zone->setOptions(options);
|
||||||
zones[zone->getId()] = zone;
|
zones[zone->getId()] = zone;
|
||||||
break;
|
break;
|
||||||
|
@ -75,7 +75,7 @@ public:
|
|||||||
void registerZone(FactionID faction);
|
void registerZone(FactionID faction);
|
||||||
ui32 getZoneCount(FactionID faction);
|
ui32 getZoneCount(FactionID faction);
|
||||||
ui32 getTotalZoneCount() const;
|
ui32 getTotalZoneCount() const;
|
||||||
void initTiles(CMapGenerator & generator);
|
void initTiles(CMapGenerator & generator, CRandomGenerator & rand);
|
||||||
void addModificators();
|
void addModificators();
|
||||||
|
|
||||||
bool isAllowedSpell(const SpellID & sid) const;
|
bool isAllowedSpell(const SpellID & sid) const;
|
||||||
|
@ -23,14 +23,14 @@ std::function<bool(const int3 &)> AREA_NO_FILTER = [](const int3 & t)
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
Zone::Zone(RmgMap & map, CMapGenerator & generator)
|
Zone::Zone(RmgMap & map, CMapGenerator & generator, CRandomGenerator & r)
|
||||||
: finished(false)
|
: finished(false)
|
||||||
, townType(ETownType::NEUTRAL)
|
, townType(ETownType::NEUTRAL)
|
||||||
, terrainType(ETerrainId::GRASS)
|
, terrainType(ETerrainId::GRASS)
|
||||||
, map(map)
|
, map(map)
|
||||||
, generator(generator)
|
, generator(generator)
|
||||||
{
|
{
|
||||||
|
rand.setSeed(r.nextInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Zone::isUnderground() const
|
bool Zone::isUnderground() const
|
||||||
@ -214,7 +214,7 @@ void Zone::fractalize()
|
|||||||
{
|
{
|
||||||
//link tiles in random order
|
//link tiles in random order
|
||||||
std::vector<int3> tilesToMakePath = possibleTiles.getTilesVector();
|
std::vector<int3> tilesToMakePath = possibleTiles.getTilesVector();
|
||||||
RandomGeneratorUtil::randomShuffle(tilesToMakePath, generator.rand);
|
RandomGeneratorUtil::randomShuffle(tilesToMakePath, getRand());
|
||||||
|
|
||||||
int3 nodeFound(-1, -1, -1);
|
int3 nodeFound(-1, -1, -1);
|
||||||
|
|
||||||
@ -290,4 +290,9 @@ void Zone::initModificators()
|
|||||||
logGlobal->info("Zone %d modificators initialized", getId());
|
logGlobal->info("Zone %d modificators initialized", getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CRandomGenerator& Zone::getRand()
|
||||||
|
{
|
||||||
|
return rand;
|
||||||
|
}
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
@ -28,6 +28,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
|||||||
class RmgMap;
|
class RmgMap;
|
||||||
class CMapGenerator;
|
class CMapGenerator;
|
||||||
class Modificator;
|
class Modificator;
|
||||||
|
class CRandomGenerator;
|
||||||
|
|
||||||
extern std::function<bool(const int3 &)> AREA_NO_FILTER;
|
extern std::function<bool(const int3 &)> AREA_NO_FILTER;
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ typedef std::list<std::shared_ptr<Modificator>> TModificators;
|
|||||||
class Zone : public rmg::ZoneOptions
|
class Zone : public rmg::ZoneOptions
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Zone(RmgMap & map, CMapGenerator & generator);
|
Zone(RmgMap & map, CMapGenerator & generator, CRandomGenerator & rand);
|
||||||
Zone(const Zone &) = delete;
|
Zone(const Zone &) = delete;
|
||||||
|
|
||||||
void setOptions(const rmg::ZoneOptions & options);
|
void setOptions(const rmg::ZoneOptions & options);
|
||||||
@ -85,12 +86,14 @@ public:
|
|||||||
|
|
||||||
void initModificators();
|
void initModificators();
|
||||||
|
|
||||||
|
CRandomGenerator & getRand();
|
||||||
public:
|
public:
|
||||||
boost::recursive_mutex areaMutex;
|
boost::recursive_mutex areaMutex;
|
||||||
using Lock = boost::unique_lock<boost::recursive_mutex>;
|
using Lock = boost::unique_lock<boost::recursive_mutex>;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CMapGenerator & generator;
|
CMapGenerator & generator;
|
||||||
|
CRandomGenerator rand;
|
||||||
RmgMap & map;
|
RmgMap & map;
|
||||||
TModificators modificators;
|
TModificators modificators;
|
||||||
bool finished;
|
bool finished;
|
||||||
|
@ -113,7 +113,7 @@ void ConnectionsPlacer::selfSideDirectConnection(const rmg::ZoneConnection & con
|
|||||||
int3 borderPos;
|
int3 borderPos;
|
||||||
while(!directConnectionIterator->second.empty())
|
while(!directConnectionIterator->second.empty())
|
||||||
{
|
{
|
||||||
borderPos = *RandomGeneratorUtil::nextItem(directConnectionIterator->second, generator.rand);
|
borderPos = *RandomGeneratorUtil::nextItem(directConnectionIterator->second, zone.getRand());
|
||||||
guardPos = zone.areaPossible().nearest(borderPos);
|
guardPos = zone.areaPossible().nearest(borderPos);
|
||||||
assert(borderPos != guardPos);
|
assert(borderPos != guardPos);
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ bool MinePlacer::placeMines(ObjectManager & manager)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Shuffle mines to avoid patterns, but don't shuffle key objects like towns
|
//Shuffle mines to avoid patterns, but don't shuffle key objects like towns
|
||||||
RandomGeneratorUtil::randomShuffle(requiredObjects, generator.rand);
|
RandomGeneratorUtil::randomShuffle(requiredObjects, zone.getRand());
|
||||||
for (const auto& obj : requiredObjects)
|
for (const auto& obj : requiredObjects)
|
||||||
{
|
{
|
||||||
manager.addRequiredObject(obj.first, obj.second);
|
manager.addRequiredObject(obj.first, obj.second);
|
||||||
@ -83,7 +83,7 @@ bool MinePlacer::placeMines(ObjectManager & manager)
|
|||||||
{
|
{
|
||||||
for(auto * mine : createdMines)
|
for(auto * mine : createdMines)
|
||||||
{
|
{
|
||||||
for(int rc = generator.rand.nextInt(1, extraRes); rc > 0; --rc)
|
for(int rc = zone.getRand().nextInt(1, extraRes); rc > 0; --rc)
|
||||||
{
|
{
|
||||||
auto * resourse = dynamic_cast<CGResource *>(VLC->objtypeh->getHandlerFor(Obj::RESOURCE, mine->producedResource)->create());
|
auto * resourse = dynamic_cast<CGResource *>(VLC->objtypeh->getHandlerFor(Obj::RESOURCE, mine->producedResource)->create());
|
||||||
resourse->amount = CGResource::RANDOM_AMOUNT;
|
resourse->amount = CGResource::RANDOM_AMOUNT;
|
||||||
|
@ -140,7 +140,7 @@ void ObjectDistributor::distributeSeerHuts()
|
|||||||
const auto & zoneMap = map.getZones();
|
const auto & zoneMap = map.getZones();
|
||||||
RmgMap::ZoneVector zones(zoneMap.begin(), zoneMap.end());
|
RmgMap::ZoneVector zones(zoneMap.begin(), zoneMap.end());
|
||||||
|
|
||||||
RandomGeneratorUtil::randomShuffle(zones, generator.rand);
|
RandomGeneratorUtil::randomShuffle(zones, zone.getRand());
|
||||||
|
|
||||||
const auto & possibleQuestArts = generator.getAllPossibleQuestArtifacts();
|
const auto & possibleQuestArts = generator.getAllPossibleQuestArtifacts();
|
||||||
size_t availableArts = possibleQuestArts.size();
|
size_t availableArts = possibleQuestArts.size();
|
||||||
@ -167,7 +167,7 @@ void ObjectDistributor::distributePrisons()
|
|||||||
const auto & zoneMap = map.getZones();
|
const auto & zoneMap = map.getZones();
|
||||||
RmgMap::ZoneVector zones(zoneMap.begin(), zoneMap.end());
|
RmgMap::ZoneVector zones(zoneMap.begin(), zoneMap.end());
|
||||||
|
|
||||||
RandomGeneratorUtil::randomShuffle(zones, generator.rand);
|
RandomGeneratorUtil::randomShuffle(zones, zone.getRand());
|
||||||
|
|
||||||
size_t allowedPrisons = generator.getPrisonsRemaning();
|
size_t allowedPrisons = generator.getPrisonsRemaning();
|
||||||
for (int i = zones.size() - 1; i >= 0; i--)
|
for (int i = zones.size() - 1; i >= 0; i--)
|
||||||
|
@ -294,7 +294,7 @@ bool ObjectManager::createRequiredObjects()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rmgNearObject.setPosition(*RandomGeneratorUtil::nextItem(possibleArea.getTiles(), generator.rand));
|
rmgNearObject.setPosition(*RandomGeneratorUtil::nextItem(possibleArea.getTiles(), zone.getRand()));
|
||||||
placeObject(rmgNearObject, false, false);
|
placeObject(rmgNearObject, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -342,7 +342,7 @@ bool ObjectManager::createRequiredObjects()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rmgNearObject.setPosition(*RandomGeneratorUtil::nextItem(possibleArea.getTiles(), generator.rand));
|
rmgNearObject.setPosition(*RandomGeneratorUtil::nextItem(possibleArea.getTiles(), zone.getRand()));
|
||||||
placeObject(rmgNearObject, false, false);
|
placeObject(rmgNearObject, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -482,10 +482,10 @@ CGCreature * ObjectManager::chooseGuard(si32 strength, bool zoneGuard)
|
|||||||
}
|
}
|
||||||
if(!possibleCreatures.empty())
|
if(!possibleCreatures.empty())
|
||||||
{
|
{
|
||||||
creId = *RandomGeneratorUtil::nextItem(possibleCreatures, generator.rand);
|
creId = *RandomGeneratorUtil::nextItem(possibleCreatures, zone.getRand());
|
||||||
amount = strength / VLC->creh->objects[creId]->getAIValue();
|
amount = strength / VLC->creh->objects[creId]->getAIValue();
|
||||||
if (amount >= 4)
|
if (amount >= 4)
|
||||||
amount = static_cast<int>(amount * generator.rand.nextDouble(0.75, 1.25));
|
amount = static_cast<int>(amount * zone.getRand().nextDouble(0.75, 1.25));
|
||||||
}
|
}
|
||||||
else //just pick any available creature
|
else //just pick any available creature
|
||||||
{
|
{
|
||||||
|
@ -45,7 +45,7 @@ void ObstaclePlacer::process()
|
|||||||
//TODO: Set prohibited area in ObstacleProxy :?
|
//TODO: Set prohibited area in ObstacleProxy :?
|
||||||
prohibitedArea = zone.freePaths() + zone.areaUsed() + manager->getVisitableArea();
|
prohibitedArea = zone.freePaths() + zone.areaUsed() + manager->getVisitableArea();
|
||||||
|
|
||||||
auto objs = createObstacles(generator.rand);
|
auto objs = createObstacles(zone.getRand());
|
||||||
mapProxy->insertObjects(objs);
|
mapProxy->insertObjects(objs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
void QuestArtifactPlacer::process()
|
void QuestArtifactPlacer::process()
|
||||||
{
|
{
|
||||||
findZonesForQuestArts();
|
findZonesForQuestArts();
|
||||||
placeQuestArtifacts(&generator.rand);
|
placeQuestArtifacts(zone.getRand());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuestArtifactPlacer::init()
|
void QuestArtifactPlacer::init()
|
||||||
@ -71,11 +71,11 @@ void QuestArtifactPlacer::findZonesForQuestArts()
|
|||||||
logGlobal->info("Number of nearby zones suitable for quest artifacts: %d", questArtZones.size());
|
logGlobal->info("Number of nearby zones suitable for quest artifacts: %d", questArtZones.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuestArtifactPlacer::placeQuestArtifacts(CRandomGenerator * rand)
|
void QuestArtifactPlacer::placeQuestArtifacts(CRandomGenerator & rand)
|
||||||
{
|
{
|
||||||
for (const auto & artifactToPlace : questArtifactsToPlace)
|
for (const auto & artifactToPlace : questArtifactsToPlace)
|
||||||
{
|
{
|
||||||
RandomGeneratorUtil::randomShuffle(questArtZones, *rand);
|
RandomGeneratorUtil::randomShuffle(questArtZones, rand);
|
||||||
for (auto zone : questArtZones)
|
for (auto zone : questArtZones)
|
||||||
{
|
{
|
||||||
auto* qap = zone->getModificator<QuestArtifactPlacer>();
|
auto* qap = zone->getModificator<QuestArtifactPlacer>();
|
||||||
@ -83,7 +83,7 @@ void QuestArtifactPlacer::placeQuestArtifacts(CRandomGenerator * rand)
|
|||||||
if (artifactsToReplace.empty())
|
if (artifactsToReplace.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto artifactToReplace = *RandomGeneratorUtil::nextItem(artifactsToReplace, *rand);
|
auto artifactToReplace = *RandomGeneratorUtil::nextItem(artifactsToReplace, rand);
|
||||||
logGlobal->info("Replacing %s at %s with the quest artifact %s",
|
logGlobal->info("Replacing %s at %s with the quest artifact %s",
|
||||||
artifactToReplace->getObjectName(),
|
artifactToReplace->getObjectName(),
|
||||||
artifactToReplace->getPosition().toString(),
|
artifactToReplace->getPosition().toString(),
|
||||||
@ -130,7 +130,7 @@ ArtifactID QuestArtifactPlacer::drawRandomArtifact()
|
|||||||
{
|
{
|
||||||
ArtifactID ret = questArtifacts.back();
|
ArtifactID ret = questArtifacts.back();
|
||||||
questArtifacts.pop_back();
|
questArtifacts.pop_back();
|
||||||
RandomGeneratorUtil::randomShuffle(questArtifacts, generator.rand);
|
RandomGeneratorUtil::randomShuffle(questArtifacts, zone.getRand());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -31,7 +31,7 @@ public:
|
|||||||
void addQuestArtifact(const ArtifactID& id);
|
void addQuestArtifact(const ArtifactID& id);
|
||||||
void rememberPotentialArtifactToReplace(CGObjectInstance* obj);
|
void rememberPotentialArtifactToReplace(CGObjectInstance* obj);
|
||||||
std::vector<CGObjectInstance*> getPossibleArtifactsToReplace() const;
|
std::vector<CGObjectInstance*> getPossibleArtifactsToReplace() const;
|
||||||
void placeQuestArtifacts(CRandomGenerator* rand);
|
void placeQuestArtifacts(CRandomGenerator & rand);
|
||||||
void dropReplacedArtifact(CGObjectInstance* obj);
|
void dropReplacedArtifact(CGObjectInstance* obj);
|
||||||
|
|
||||||
size_t getMaxQuestArtifactCount() const;
|
size_t getMaxQuestArtifactCount() const;
|
||||||
|
@ -88,7 +88,7 @@ void RiverPlacer::init()
|
|||||||
void RiverPlacer::drawRivers()
|
void RiverPlacer::drawRivers()
|
||||||
{
|
{
|
||||||
auto tiles = rivers.getTilesVector();
|
auto tiles = rivers.getTilesVector();
|
||||||
mapProxy->drawRivers(generator.rand, tiles, zone.getTerrainType());
|
mapProxy->drawRivers(zone.getRand(), tiles, zone.getTerrainType());
|
||||||
}
|
}
|
||||||
|
|
||||||
char RiverPlacer::dump(const int3 & t)
|
char RiverPlacer::dump(const int3 & t)
|
||||||
@ -137,7 +137,7 @@ void RiverPlacer::prepareHeightmap()
|
|||||||
|
|
||||||
for(const auto & t : zone.area().getTilesVector())
|
for(const auto & t : zone.area().getTilesVector())
|
||||||
{
|
{
|
||||||
heightMap[t] = generator.rand.nextInt(5);
|
heightMap[t] = zone.getRand().nextInt(5);
|
||||||
|
|
||||||
if(roads.contains(t))
|
if(roads.contains(t))
|
||||||
heightMap[t] += 30.f;
|
heightMap[t] += 30.f;
|
||||||
@ -183,13 +183,13 @@ void RiverPlacer::preprocess()
|
|||||||
//looking outside map
|
//looking outside map
|
||||||
if(!outOfMapInternal.empty())
|
if(!outOfMapInternal.empty())
|
||||||
{
|
{
|
||||||
auto elem = *RandomGeneratorUtil::nextItem(outOfMapInternal.getTilesVector(), generator.rand);
|
auto elem = *RandomGeneratorUtil::nextItem(outOfMapInternal.getTilesVector(), zone.getRand());
|
||||||
source.add(elem);
|
source.add(elem);
|
||||||
outOfMapInternal.erase(elem);
|
outOfMapInternal.erase(elem);
|
||||||
}
|
}
|
||||||
if(!outOfMapInternal.empty())
|
if(!outOfMapInternal.empty())
|
||||||
{
|
{
|
||||||
auto elem = *RandomGeneratorUtil::nextItem(outOfMapInternal.getTilesVector(), generator.rand);
|
auto elem = *RandomGeneratorUtil::nextItem(outOfMapInternal.getTilesVector(), zone.getRand());
|
||||||
sink.add(elem);
|
sink.add(elem);
|
||||||
outOfMapInternal.erase(elem);
|
outOfMapInternal.erase(elem);
|
||||||
}
|
}
|
||||||
@ -294,7 +294,7 @@ void RiverPlacer::preprocess()
|
|||||||
//decorative river
|
//decorative river
|
||||||
if(!sink.empty() && !source.empty() && riverNodes.empty() && !zone.areaPossible().empty())
|
if(!sink.empty() && !source.empty() && riverNodes.empty() && !zone.areaPossible().empty())
|
||||||
{
|
{
|
||||||
addRiverNode(*RandomGeneratorUtil::nextItem(source.getTilesVector(), generator.rand));
|
addRiverNode(*RandomGeneratorUtil::nextItem(source.getTilesVector(), zone.getRand()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.empty())
|
if(source.empty())
|
||||||
|
@ -90,7 +90,7 @@ void RoadPlacer::drawRoads(bool secondary)
|
|||||||
|
|
||||||
std::string roadName = (secondary ? generator.getConfig().secondaryRoadType : generator.getConfig().defaultRoadType);
|
std::string roadName = (secondary ? generator.getConfig().secondaryRoadType : generator.getConfig().defaultRoadType);
|
||||||
RoadId roadType(*VLC->modh->identifiers.getIdentifier(CModHandler::scopeGame(), "road", roadName));
|
RoadId roadType(*VLC->modh->identifiers.getIdentifier(CModHandler::scopeGame(), "road", roadName));
|
||||||
mapProxy->drawRoads(generator.rand, tiles, roadType);
|
mapProxy->drawRoads(zone.getRand(), tiles, roadType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoadPlacer::addRoadNode(const int3& node)
|
void RoadPlacer::addRoadNode(const int3& node)
|
||||||
|
@ -53,20 +53,22 @@ void RockFiller::processMap()
|
|||||||
//Merge all areas
|
//Merge all areas
|
||||||
for(auto & z : map.getZones())
|
for(auto & z : map.getZones())
|
||||||
{
|
{
|
||||||
if(auto * m = z.second->getModificator<RockPlacer>())
|
auto zone = z.second;
|
||||||
|
if(auto * m = zone->getModificator<RockPlacer>())
|
||||||
{
|
{
|
||||||
auto tiles = m->rockArea.getTilesVector();
|
auto tiles = m->rockArea.getTilesVector();
|
||||||
mapProxy->drawTerrain(generator.rand, tiles, m->rockTerrain);
|
mapProxy->drawTerrain(zone->getRand(), tiles, m->rockTerrain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto & z : map.getZones())
|
for(auto & z : map.getZones())
|
||||||
{
|
{
|
||||||
if(auto * m = z.second->getModificator<RockPlacer>())
|
auto zone = z.second;
|
||||||
|
if(auto * m = zone->getModificator<RockPlacer>())
|
||||||
{
|
{
|
||||||
//Now make sure all accessible tiles have no additional rock on them
|
//Now make sure all accessible tiles have no additional rock on them
|
||||||
auto tiles = m->accessibleArea.getTilesVector();
|
auto tiles = m->accessibleArea.getTilesVector();
|
||||||
mapProxy->drawTerrain(generator.rand, tiles, z.second->getTerrainType());
|
mapProxy->drawTerrain(zone->getRand(), tiles, zone->getTerrainType());
|
||||||
|
|
||||||
m->postProcess();
|
m->postProcess();
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ void TerrainPainter::process()
|
|||||||
initTerrainType();
|
initTerrainType();
|
||||||
|
|
||||||
auto v = zone.getArea().getTilesVector();
|
auto v = zone.getArea().getTilesVector();
|
||||||
mapProxy->drawTerrain(generator.rand, v, zone.getTerrainType());
|
mapProxy->drawTerrain(zone.getRand(), v, zone.getTerrainType());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerrainPainter::init()
|
void TerrainPainter::init()
|
||||||
@ -50,7 +50,7 @@ void TerrainPainter::initTerrainType()
|
|||||||
if(terrain->isWater())
|
if(terrain->isWater())
|
||||||
waterTerrains.push_back(terrain->getId());
|
waterTerrains.push_back(terrain->getId());
|
||||||
|
|
||||||
zone.setTerrainType(*RandomGeneratorUtil::nextItem(waterTerrains, generator.rand));
|
zone.setTerrainType(*RandomGeneratorUtil::nextItem(waterTerrains, zone.getRand()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -78,7 +78,7 @@ void TerrainPainter::initTerrainType()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
zone.setTerrainType(*RandomGeneratorUtil::nextItem(terrainTypes, generator.rand));
|
zone.setTerrainType(*RandomGeneratorUtil::nextItem(terrainTypes, zone.getRand()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,16 +119,16 @@ void TownPlacer::placeTowns(ObjectManager & manager)
|
|||||||
if(!totalTowns) //if there's no town present, get random faction for dwellings and pandoras
|
if(!totalTowns) //if there's no town present, get random faction for dwellings and pandoras
|
||||||
{
|
{
|
||||||
//25% chance for neutral
|
//25% chance for neutral
|
||||||
if (generator.rand.nextInt(1, 100) <= 25)
|
if (zone.getRand().nextInt(1, 100) <= 25)
|
||||||
{
|
{
|
||||||
zone.setTownType(ETownType::NEUTRAL);
|
zone.setTownType(ETownType::NEUTRAL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!zone.getTownTypes().empty())
|
if(!zone.getTownTypes().empty())
|
||||||
zone.setTownType(*RandomGeneratorUtil::nextItem(zone.getTownTypes(), generator.rand));
|
zone.setTownType(*RandomGeneratorUtil::nextItem(zone.getTownTypes(), zone.getRand()));
|
||||||
else if(!zone.getMonsterTypes().empty())
|
else if(!zone.getMonsterTypes().empty())
|
||||||
zone.setTownType(*RandomGeneratorUtil::nextItem(zone.getMonsterTypes(), generator.rand)); //this happens in Clash of Dragons in treasure zones, where all towns are banned
|
zone.setTownType(*RandomGeneratorUtil::nextItem(zone.getMonsterTypes(), zone.getRand())); //this happens in Clash of Dragons in treasure zones, where all towns are banned
|
||||||
else //just in any case
|
else //just in any case
|
||||||
zone.setTownType(getRandomTownType());
|
zone.setTownType(getRandomTownType());
|
||||||
}
|
}
|
||||||
@ -182,9 +182,9 @@ void TownPlacer::addNewTowns(int count, bool hasFort, const PlayerColor & player
|
|||||||
if(!zone.areTownsSameType())
|
if(!zone.areTownsSameType())
|
||||||
{
|
{
|
||||||
if(!zone.getTownTypes().empty())
|
if(!zone.getTownTypes().empty())
|
||||||
subType = *RandomGeneratorUtil::nextItem(zone.getTownTypes(), generator.rand);
|
subType = *RandomGeneratorUtil::nextItem(zone.getTownTypes(), zone.getRand());
|
||||||
else
|
else
|
||||||
subType = *RandomGeneratorUtil::nextItem(zone.getDefaultTownTypes(), generator.rand); //it is possible to have zone with no towns allowed
|
subType = *RandomGeneratorUtil::nextItem(zone.getDefaultTownTypes(), zone.getRand()); //it is possible to have zone with no towns allowed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +235,7 @@ si32 TownPlacer::getRandomTownType(bool matchUndergroundType)
|
|||||||
townTypesAllowed = townTypesVerify;
|
townTypesAllowed = townTypesVerify;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *RandomGeneratorUtil::nextItem(townTypesAllowed, generator.rand);
|
return *RandomGeneratorUtil::nextItem(townTypesAllowed, zone.getRand());
|
||||||
}
|
}
|
||||||
|
|
||||||
int TownPlacer::getTotalTowns() const
|
int TownPlacer::getTotalTowns() const
|
||||||
|
@ -110,7 +110,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
oi.generateObject = [i, this]() -> CGObjectInstance *
|
oi.generateObject = [i, this]() -> CGObjectInstance *
|
||||||
{
|
{
|
||||||
auto possibleHeroes = generator.getAllPossibleHeroes();
|
auto possibleHeroes = generator.getAllPossibleHeroes();
|
||||||
HeroTypeID hid = *RandomGeneratorUtil::nextItem(possibleHeroes, generator.rand);
|
HeroTypeID hid = *RandomGeneratorUtil::nextItem(possibleHeroes, zone.getRand());
|
||||||
|
|
||||||
auto factory = VLC->objtypeh->getHandlerFor(Obj::PRISON, 0);
|
auto factory = VLC->objtypeh->getHandlerFor(Obj::PRISON, 0);
|
||||||
auto * obj = dynamic_cast<CGHeroInstance *>(factory->create());
|
auto * obj = dynamic_cast<CGHeroInstance *>(factory->create());
|
||||||
@ -208,7 +208,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
out.push_back(spell->id);
|
out.push_back(spell->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto * a = CArtifactInstance::createScroll(*RandomGeneratorUtil::nextItem(out, generator.rand));
|
auto * a = CArtifactInstance::createScroll(*RandomGeneratorUtil::nextItem(out, zone.getRand()));
|
||||||
obj->storedArtifact = a;
|
obj->storedArtifact = a;
|
||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
@ -322,7 +322,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
spells.push_back(spell);
|
spells.push_back(spell);
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomGeneratorUtil::randomShuffle(spells, generator.rand);
|
RandomGeneratorUtil::randomShuffle(spells, zone.getRand());
|
||||||
for(int j = 0; j < std::min(12, static_cast<int>(spells.size())); j++)
|
for(int j = 0; j < std::min(12, static_cast<int>(spells.size())); j++)
|
||||||
{
|
{
|
||||||
obj->spells.push_back(spells[j]->id);
|
obj->spells.push_back(spells[j]->id);
|
||||||
@ -351,7 +351,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
spells.push_back(spell);
|
spells.push_back(spell);
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomGeneratorUtil::randomShuffle(spells, generator.rand);
|
RandomGeneratorUtil::randomShuffle(spells, zone.getRand());
|
||||||
for(int j = 0; j < std::min(15, static_cast<int>(spells.size())); j++)
|
for(int j = 0; j < std::min(15, static_cast<int>(spells.size())); j++)
|
||||||
{
|
{
|
||||||
obj->spells.push_back(spells[j]->id);
|
obj->spells.push_back(spells[j]->id);
|
||||||
@ -379,7 +379,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
spells.push_back(spell);
|
spells.push_back(spell);
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomGeneratorUtil::randomShuffle(spells, generator.rand);
|
RandomGeneratorUtil::randomShuffle(spells, zone.getRand());
|
||||||
for(int j = 0; j < std::min(60, static_cast<int>(spells.size())); j++)
|
for(int j = 0; j < std::min(60, static_cast<int>(spells.size())); j++)
|
||||||
{
|
{
|
||||||
obj->spells.push_back(spells[j]->id);
|
obj->spells.push_back(spells[j]->id);
|
||||||
@ -411,7 +411,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
//14 creatures per town + 4 for each of gold / exp reward
|
//14 creatures per town + 4 for each of gold / exp reward
|
||||||
possibleSeerHuts.reserve(14 + 4 + 4);
|
possibleSeerHuts.reserve(14 + 4 + 4);
|
||||||
|
|
||||||
RandomGeneratorUtil::randomShuffle(creatures, generator.rand);
|
RandomGeneratorUtil::randomShuffle(creatures, zone.getRand());
|
||||||
|
|
||||||
for(int i = 0; i < static_cast<int>(creatures.size()); i++)
|
for(int i = 0; i < static_cast<int>(creatures.size()); i++)
|
||||||
{
|
{
|
||||||
@ -421,7 +421,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
if(!creaturesAmount)
|
if(!creaturesAmount)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int randomAppearance = chooseRandomAppearance(generator.rand, Obj::SEER_HUT, zone.getTerrainType());
|
int randomAppearance = chooseRandomAppearance(zone.getRand(), Obj::SEER_HUT, zone.getTerrainType());
|
||||||
|
|
||||||
oi.generateObject = [creature, creaturesAmount, randomAppearance, this, qap]() -> CGObjectInstance *
|
oi.generateObject = [creature, creaturesAmount, randomAppearance, this, qap]() -> CGObjectInstance *
|
||||||
{
|
{
|
||||||
@ -459,7 +459,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
static int seerLevels = std::min(generator.getConfig().questValues.size(), generator.getConfig().questRewardValues.size());
|
static int seerLevels = std::min(generator.getConfig().questValues.size(), generator.getConfig().questRewardValues.size());
|
||||||
for(int i = 0; i < seerLevels; i++) //seems that code for exp and gold reward is similiar
|
for(int i = 0; i < seerLevels; i++) //seems that code for exp and gold reward is similiar
|
||||||
{
|
{
|
||||||
int randomAppearance = chooseRandomAppearance(generator.rand, Obj::SEER_HUT, zone.getTerrainType());
|
int randomAppearance = chooseRandomAppearance(zone.getRand(), Obj::SEER_HUT, zone.getTerrainType());
|
||||||
|
|
||||||
oi.setTemplate(Obj::SEER_HUT, randomAppearance, zone.getTerrainType());
|
oi.setTemplate(Obj::SEER_HUT, randomAppearance, zone.getTerrainType());
|
||||||
oi.value = generator.getConfig().questValues[i];
|
oi.value = generator.getConfig().questValues[i];
|
||||||
@ -519,7 +519,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
|
|
||||||
for (size_t i = 0; i < questArtsRemaining; i++)
|
for (size_t i = 0; i < questArtsRemaining; i++)
|
||||||
{
|
{
|
||||||
addObjectToRandomPool(*RandomGeneratorUtil::nextItem(possibleSeerHuts, generator.rand));
|
addObjectToRandomPool(*RandomGeneratorUtil::nextItem(possibleSeerHuts, zone.getRand()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -553,7 +553,7 @@ std::vector<ObjectInfo*> TreasurePlacer::prepareTreasurePile(const CTreasureInfo
|
|||||||
int maxValue = treasureInfo.max;
|
int maxValue = treasureInfo.max;
|
||||||
int minValue = treasureInfo.min;
|
int minValue = treasureInfo.min;
|
||||||
|
|
||||||
const ui32 desiredValue = generator.rand.nextInt(minValue, maxValue);
|
const ui32 desiredValue =zone.getRand().nextInt(minValue, maxValue);
|
||||||
|
|
||||||
int currentValue = 0;
|
int currentValue = 0;
|
||||||
bool hasLargeObject = false;
|
bool hasLargeObject = false;
|
||||||
@ -631,7 +631,7 @@ rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*>
|
|||||||
bestPositions = accessibleArea.getTilesVector();
|
bestPositions = accessibleArea.getTilesVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
int3 nextPos = *RandomGeneratorUtil::nextItem(bestPositions, generator.rand);
|
int3 nextPos = *RandomGeneratorUtil::nextItem(bestPositions, zone.getRand());
|
||||||
instance.setPosition(nextPos - rmgObject.getPosition());
|
instance.setPosition(nextPos - rmgObject.getPosition());
|
||||||
|
|
||||||
auto instanceAccessibleArea = instance.getAccessibleArea();
|
auto instanceAccessibleArea = instance.getAccessibleArea();
|
||||||
@ -686,7 +686,7 @@ ObjectInfo * TreasurePlacer::getRandomObject(ui32 desiredValue, ui32 currentValu
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int r = generator.rand.nextInt(1, total);
|
int r = zone.getRand().nextInt(1, total);
|
||||||
auto sorter = [](const std::pair<ui32, ObjectInfo *> & rhs, const ui32 lhs) -> bool
|
auto sorter = [](const std::pair<ui32, ObjectInfo *> & rhs, const ui32 lhs) -> bool
|
||||||
{
|
{
|
||||||
return static_cast<int>(rhs.first) < lhs;
|
return static_cast<int>(rhs.first) < lhs;
|
||||||
|
@ -58,8 +58,8 @@ void WaterAdopter::createWater(EWaterContent::EWaterContent waterContent)
|
|||||||
if(waterContent == EWaterContent::NORMAL)
|
if(waterContent == EWaterContent::NORMAL)
|
||||||
{
|
{
|
||||||
waterArea.unite(collectDistantTiles(zone, zone.getSize() - 1));
|
waterArea.unite(collectDistantTiles(zone, zone.getSize() - 1));
|
||||||
auto sliceStart = RandomGeneratorUtil::nextItem(reverseDistanceMap[0], generator.rand);
|
auto sliceStart = RandomGeneratorUtil::nextItem(reverseDistanceMap[0], zone.getRand());
|
||||||
auto sliceEnd = RandomGeneratorUtil::nextItem(reverseDistanceMap[0], generator.rand);
|
auto sliceEnd = RandomGeneratorUtil::nextItem(reverseDistanceMap[0], zone.getRand());
|
||||||
|
|
||||||
//at least 25% without water
|
//at least 25% without water
|
||||||
bool endPassed = false;
|
bool endPassed = false;
|
||||||
@ -97,7 +97,7 @@ void WaterAdopter::createWater(EWaterContent::EWaterContent waterContent)
|
|||||||
const int coastLength = reverseDistanceMap[coastId].size() / (coastId + 3);
|
const int coastLength = reverseDistanceMap[coastId].size() / (coastId + 3);
|
||||||
for(int coastIter = 0; coastIter < coastLength; ++coastIter)
|
for(int coastIter = 0; coastIter < coastLength; ++coastIter)
|
||||||
{
|
{
|
||||||
int3 tile = *RandomGeneratorUtil::nextItem(reverseDistanceMap[coastId], generator.rand);
|
int3 tile = *RandomGeneratorUtil::nextItem(reverseDistanceMap[coastId], zone.getRand());
|
||||||
if(tilesChecked.find(tile) != tilesChecked.end())
|
if(tilesChecked.find(tile) != tilesChecked.end())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ void WaterProxy::process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto v = zone.getArea().getTilesVector();
|
auto v = zone.getArea().getTilesVector();
|
||||||
mapProxy->drawTerrain(generator.rand, v, zone.getTerrainType());
|
mapProxy->drawTerrain(zone.getRand(), v, zone.getTerrainType());
|
||||||
|
|
||||||
//check terrain type
|
//check terrain type
|
||||||
for([[maybe_unused]] const auto & t : zone.area().getTilesVector())
|
for([[maybe_unused]] const auto & t : zone.area().getTilesVector())
|
||||||
@ -216,7 +216,7 @@ bool WaterProxy::placeBoat(Zone & land, const Lake & lake, RouteInfo & info)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto subObjects = VLC->objtypeh->knownSubObjects(Obj::BOAT);
|
auto subObjects = VLC->objtypeh->knownSubObjects(Obj::BOAT);
|
||||||
auto * boat = dynamic_cast<CGBoat *>(VLC->objtypeh->getHandlerFor(Obj::BOAT, *RandomGeneratorUtil::nextItem(subObjects, generator.rand))->create());
|
auto * boat = dynamic_cast<CGBoat *>(VLC->objtypeh->getHandlerFor(Obj::BOAT, *RandomGeneratorUtil::nextItem(subObjects, zone.getRand()))->create());
|
||||||
|
|
||||||
rmg::Object rmgObject(*boat);
|
rmg::Object rmgObject(*boat);
|
||||||
rmgObject.setTemplate(zone.getTerrainType());
|
rmgObject.setTemplate(zone.getTerrainType());
|
||||||
@ -279,7 +279,7 @@ bool WaterProxy::placeShipyard(Zone & land, const Lake & lake, si32 guard, Route
|
|||||||
if(!manager)
|
if(!manager)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int subtype = chooseRandomAppearance(generator.rand, Obj::SHIPYARD, land.getTerrainType());
|
int subtype = chooseRandomAppearance(zone.getRand(), Obj::SHIPYARD, land.getTerrainType());
|
||||||
auto * shipyard = dynamic_cast<CGShipyard *>(VLC->objtypeh->getHandlerFor(Obj::SHIPYARD, subtype)->create());
|
auto * shipyard = dynamic_cast<CGShipyard *>(VLC->objtypeh->getHandlerFor(Obj::SHIPYARD, subtype)->create());
|
||||||
shipyard->tempOwner = PlayerColor::NEUTRAL;
|
shipyard->tempOwner = PlayerColor::NEUTRAL;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user