mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
First implementation that works
This commit is contained in:
parent
4d948e8c6d
commit
67447acd0e
@ -64,6 +64,10 @@ void ObstaclePlacer::process()
|
|||||||
areaPossible->subtract(blockedArea);
|
areaPossible->subtract(blockedArea);
|
||||||
|
|
||||||
prohibitedArea = zone.freePaths() + areaUsed + manager->getVisitableArea();
|
prohibitedArea = zone.freePaths() + areaUsed + manager->getVisitableArea();
|
||||||
|
if (auto * rp = zone.getModificator<RoadPlacer>())
|
||||||
|
{
|
||||||
|
prohibitedArea.unite(rp->getRoads());
|
||||||
|
}
|
||||||
|
|
||||||
//Progressively block tiles, but make sure they don't seal any gap between blocks
|
//Progressively block tiles, but make sure they don't seal any gap between blocks
|
||||||
rmg::Area toBlock;
|
rmg::Area toBlock;
|
||||||
@ -116,7 +120,7 @@ void ObstaclePlacer::init()
|
|||||||
DEPENDENCY(RoadPlacer);
|
DEPENDENCY(RoadPlacer);
|
||||||
if (zone.isUnderground())
|
if (zone.isUnderground())
|
||||||
{
|
{
|
||||||
DEPENDENCY(RockFiller);
|
DEPENDENCY_ALL(RockFiller);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -34,6 +34,12 @@ void RoadPlacer::process()
|
|||||||
connectRoads();
|
connectRoads();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RoadPlacer::postProcess()
|
||||||
|
{
|
||||||
|
//Draw dirt roads if there are only mines
|
||||||
|
drawRoads(noRoadNodes);
|
||||||
|
}
|
||||||
|
|
||||||
void RoadPlacer::init()
|
void RoadPlacer::init()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -140,8 +146,9 @@ void RoadPlacer::drawRoads(bool secondary)
|
|||||||
return !terrain->isPassable() || !terrain->isLand();
|
return !terrain->isPassable() || !terrain->isLand();
|
||||||
});
|
});
|
||||||
|
|
||||||
zone.areaPossible()->subtract(roads);
|
// FIXME: This area should still be available after road is created
|
||||||
zone.freePaths()->unite(roads);
|
//zone.areaPossible()->subtract(roads);
|
||||||
|
//zone.freePaths()->unite(roads);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!generator.getMapGenOptions().isRoadEnabled())
|
if(!generator.getMapGenOptions().isRoadEnabled())
|
||||||
@ -175,12 +182,11 @@ void RoadPlacer::drawRoads(bool secondary)
|
|||||||
void RoadPlacer::addRoadNode(const int3& node)
|
void RoadPlacer::addRoadNode(const int3& node)
|
||||||
{
|
{
|
||||||
RecursiveLock lock(externalAccessMutex);
|
RecursiveLock lock(externalAccessMutex);
|
||||||
roadNodes.insert(node);
|
roadNodes.push_back(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoadPlacer::connectRoads()
|
void RoadPlacer::connectRoads()
|
||||||
{
|
{
|
||||||
bool noRoadNodes = false;
|
|
||||||
//Assumes objects are already placed
|
//Assumes objects are already placed
|
||||||
if(roadNodes.size() < 2)
|
if(roadNodes.size() < 2)
|
||||||
{
|
{
|
||||||
@ -220,13 +226,16 @@ void RoadPlacer::connectRoads()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Draw dirt roads if there are only mines
|
if (!zone.isUnderground())
|
||||||
drawRoads(noRoadNodes);
|
{
|
||||||
|
// Otherwise roads will be drawn only after rock is placed
|
||||||
|
postProcess();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char RoadPlacer::dump(const int3 & t)
|
char RoadPlacer::dump(const int3 & t)
|
||||||
{
|
{
|
||||||
if(roadNodes.count(t))
|
if(vstd::contains(roadNodes, t))
|
||||||
return '@';
|
return '@';
|
||||||
if(roads.contains(t))
|
if(roads.contains(t))
|
||||||
return '+';
|
return '+';
|
||||||
|
@ -19,6 +19,7 @@ public:
|
|||||||
MODIFICATOR(RoadPlacer);
|
MODIFICATOR(RoadPlacer);
|
||||||
|
|
||||||
void process() override;
|
void process() override;
|
||||||
|
void postProcess();
|
||||||
void init() override;
|
void init() override;
|
||||||
char dump(const int3 &) override;
|
char dump(const int3 &) override;
|
||||||
|
|
||||||
@ -36,11 +37,13 @@ protected:
|
|||||||
void drawRoads(bool secondary = false); //actually updates tiles
|
void drawRoads(bool secondary = false); //actually updates tiles
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
rmg::Tileset roadNodes; //tiles to be connected with roads
|
std::vector<int3> roadNodes; //tiles to be connected with roads
|
||||||
rmg::Area roads; //all tiles with roads
|
rmg::Area roads; //all tiles with roads
|
||||||
rmg::Area areaRoads;
|
rmg::Area areaRoads;
|
||||||
rmg::Area isolated;
|
rmg::Area isolated;
|
||||||
rmg::Area visitableTiles; // Tiles occupied by removable or passable objects
|
rmg::Area visitableTiles; // Tiles occupied by removable or passable objects
|
||||||
|
|
||||||
|
bool noRoadNodes = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "TreasurePlacer.h"
|
#include "TreasurePlacer.h"
|
||||||
#include "ObjectManager.h"
|
#include "ObjectManager.h"
|
||||||
#include "RiverPlacer.h"
|
#include "RiverPlacer.h"
|
||||||
|
#include "RoadPlacer.h"
|
||||||
#include "../RmgMap.h"
|
#include "../RmgMap.h"
|
||||||
#include "../CMapGenerator.h"
|
#include "../CMapGenerator.h"
|
||||||
#include "../Functions.h"
|
#include "../Functions.h"
|
||||||
@ -35,7 +36,7 @@ void RockFiller::process()
|
|||||||
void RockFiller::processMap()
|
void RockFiller::processMap()
|
||||||
{
|
{
|
||||||
//Merge all areas
|
//Merge all areas
|
||||||
for(auto & z : map.getZones())
|
for(auto & z : map.getZonesOnLevel(1))
|
||||||
{
|
{
|
||||||
auto zone = z.second;
|
auto zone = z.second;
|
||||||
if(auto * m = zone->getModificator<RockPlacer>())
|
if(auto * m = zone->getModificator<RockPlacer>())
|
||||||
@ -45,7 +46,7 @@ void RockFiller::processMap()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto & z : map.getZones())
|
for(auto & z : map.getZonesOnLevel(1))
|
||||||
{
|
{
|
||||||
auto zone = z.second;
|
auto zone = z.second;
|
||||||
if(auto * m = zone->getModificator<RockPlacer>())
|
if(auto * m = zone->getModificator<RockPlacer>())
|
||||||
@ -56,6 +57,12 @@ void RockFiller::processMap()
|
|||||||
|
|
||||||
m->postProcess();
|
m->postProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw roads after rock is placed
|
||||||
|
if(auto * rp = zone->getModificator<RoadPlacer>())
|
||||||
|
{
|
||||||
|
rp->postProcess();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,14 +30,21 @@ void RockPlacer::process()
|
|||||||
{
|
{
|
||||||
blockRock();
|
blockRock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RockPlacer::blockRock()
|
void RockPlacer::blockRock()
|
||||||
{
|
{
|
||||||
rockTerrain = VLC->terrainTypeHandler->getById(zone.getTerrainType())->rockTerrain;
|
rockTerrain = VLC->terrainTypeHandler->getById(zone.getTerrainType())->rockTerrain;
|
||||||
assert(!VLC->terrainTypeHandler->getById(rockTerrain)->isPassable());
|
assert(!VLC->terrainTypeHandler->getById(rockTerrain)->isPassable());
|
||||||
|
|
||||||
accessibleArea = zone.freePaths() + zone.areaUsed();
|
accessibleArea = zone.freePaths() + zone.areaUsed();
|
||||||
|
if(auto * rp = zone.getModificator<RoadPlacer>())
|
||||||
|
{
|
||||||
|
accessibleArea.unite(rp->getRoads());
|
||||||
|
}
|
||||||
if(auto * m = zone.getModificator<ObjectManager>())
|
if(auto * m = zone.getModificator<ObjectManager>())
|
||||||
|
{
|
||||||
accessibleArea.unite(m->getVisitableArea());
|
accessibleArea.unite(m->getVisitableArea());
|
||||||
|
}
|
||||||
|
|
||||||
//negative approach - create rock tiles first, then make sure all accessible tiles have no rock
|
//negative approach - create rock tiles first, then make sure all accessible tiles have no rock
|
||||||
rockArea = zone.area()->getSubarea([this](const int3 & t)
|
rockArea = zone.area()->getSubarea([this](const int3 & t)
|
||||||
@ -56,6 +63,12 @@ void RockPlacer::postProcess()
|
|||||||
return !map.getTile(t).terType->isPassable();
|
return !map.getTile(t).terType->isPassable();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Do not place rock on roads
|
||||||
|
if(auto * rp = zone.getModificator<RoadPlacer>())
|
||||||
|
{
|
||||||
|
rockArea.subtract(rp->getRoads());
|
||||||
|
}
|
||||||
|
|
||||||
zone.areaUsed()->unite(rockArea);
|
zone.areaUsed()->unite(rockArea);
|
||||||
zone.areaPossible()->subtract(rockArea);
|
zone.areaPossible()->subtract(rockArea);
|
||||||
}
|
}
|
||||||
@ -70,9 +83,8 @@ void RockPlacer::postProcess()
|
|||||||
|
|
||||||
void RockPlacer::init()
|
void RockPlacer::init()
|
||||||
{
|
{
|
||||||
for (const auto& zone : map.getZones())
|
DEPENDENCY(RoadPlacer);
|
||||||
{
|
for (const auto& zone : map.getZonesOnLevel(1))
|
||||||
if (zone.second->isUnderground())
|
|
||||||
{
|
{
|
||||||
auto * tp = zone.second->getModificator<TreasurePlacer>();
|
auto * tp = zone.second->getModificator<TreasurePlacer>();
|
||||||
if (tp)
|
if (tp)
|
||||||
@ -81,7 +93,6 @@ void RockPlacer::init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
char RockPlacer::dump(const int3 & t)
|
char RockPlacer::dump(const int3 & t)
|
||||||
{
|
{
|
||||||
|
@ -937,7 +937,7 @@ void TreasurePlacer::createTreasures(ObjectManager& manager)
|
|||||||
|
|
||||||
if (guarded)
|
if (guarded)
|
||||||
{
|
{
|
||||||
// TODO: Guard cannot be adjacent to road, but blocked side of an object could be
|
// Guard cannot be adjacent to road, but blocked side of an object could be
|
||||||
searchArea.subtract(roads);
|
searchArea.subtract(roads);
|
||||||
|
|
||||||
path = manager.placeAndConnectObject(searchArea, rmgObject, [this, &rmgObject, &minDistance, &manager, &nextToRoad](const int3& tile)
|
path = manager.placeAndConnectObject(searchArea, rmgObject, [this, &rmgObject, &minDistance, &manager, &nextToRoad](const int3& tile)
|
||||||
@ -967,6 +967,12 @@ void TreasurePlacer::createTreasures(ObjectManager& manager)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Do not place non-removable objects on roads
|
||||||
|
if (!rmgObject.getRemovableArea().contains(rmgObject.getArea()))
|
||||||
|
{
|
||||||
|
searchArea.subtract(roads);
|
||||||
|
}
|
||||||
|
|
||||||
path = manager.placeAndConnectObject(searchArea, rmgObject, minDistance, guarded, false, ObjectManager::OptimizeType::DISTANCE);
|
path = manager.placeAndConnectObject(searchArea, rmgObject, minDistance, guarded, false, ObjectManager::OptimizeType::DISTANCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user