1
0
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:
Tomasz Zieliński 2024-05-01 09:16:10 +02:00
parent 4d948e8c6d
commit 67447acd0e
6 changed files with 59 additions and 19 deletions

View File

@ -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
{ {

View File

@ -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 '+';

View File

@ -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

View File

@ -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();
}
} }
} }

View File

@ -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)
{ {

View File

@ -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);
} }
} }