mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-21 00:19:29 +02:00
Zones will get random network of passable paths inside them. Treasures will try to fill all remaining fields.
This commit is contained in:
@ -219,6 +219,7 @@ void CMapGenerator::fillZones()
|
|||||||
{
|
{
|
||||||
//make sure all connections are passable before creating borders
|
//make sure all connections are passable before creating borders
|
||||||
it.second->createBorder(this);
|
it.second->createBorder(this);
|
||||||
|
it.second->fractalize(this);
|
||||||
it.second->fill(this);
|
it.second->fill(this);
|
||||||
}
|
}
|
||||||
logGlobal->infoStream() << "Zones filled successfully";
|
logGlobal->infoStream() << "Zones filled successfully";
|
||||||
|
@ -357,7 +357,78 @@ void CRmgTemplateZone::createBorder(CMapGenerator* gen)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CRmgTemplateZone::crunchPath (CMapGenerator* gen, const int3 &src, const int3 &dst, TRmgTemplateZoneId zone)
|
void CRmgTemplateZone::fractalize(CMapGenerator* gen)
|
||||||
|
{
|
||||||
|
std::vector<int3> clearedTiles;
|
||||||
|
std::set<int3> possibleTiles;
|
||||||
|
std::set<int3> tilesToClear; //will be set clear
|
||||||
|
std::set<int3> tilesToIgnore; //will be erased in this iteration
|
||||||
|
|
||||||
|
const float minDistance = std::sqrt(totalDensity);
|
||||||
|
for (auto tile : tileinfo)
|
||||||
|
{
|
||||||
|
if (gen->isFree(tile))
|
||||||
|
clearedTiles.push_back(tile);
|
||||||
|
else if (gen->isPossible(tile));
|
||||||
|
possibleTiles.insert(tile);
|
||||||
|
}
|
||||||
|
if (clearedTiles.empty()) //this should come from zone connections
|
||||||
|
{
|
||||||
|
clearedTiles.push_back(pos); //zone center should be always clear
|
||||||
|
}
|
||||||
|
|
||||||
|
while (possibleTiles.size())
|
||||||
|
{
|
||||||
|
for (auto tileToMakePath : possibleTiles)
|
||||||
|
{
|
||||||
|
//find closest free tile
|
||||||
|
float currentDistance = 1e10;
|
||||||
|
int3 closestTile (-1,-1,-1);
|
||||||
|
|
||||||
|
for (auto clearTile : clearedTiles)
|
||||||
|
{
|
||||||
|
float distance = tileToMakePath.dist2d(clearTile);
|
||||||
|
|
||||||
|
if (distance < currentDistance)
|
||||||
|
{
|
||||||
|
currentDistance = distance;
|
||||||
|
closestTile = clearTile;
|
||||||
|
}
|
||||||
|
if (currentDistance <= minDistance)
|
||||||
|
{
|
||||||
|
//this tile is close enough. Forget about it and check next one
|
||||||
|
tilesToIgnore.insert (tileToMakePath);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if tiles is not close enough, make path to it
|
||||||
|
if (currentDistance > minDistance)
|
||||||
|
{
|
||||||
|
crunchPath (gen, tileToMakePath, closestTile, id, &tilesToClear);
|
||||||
|
break; //next iteration - use already cleared tiles
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto tileToClear : tilesToClear)
|
||||||
|
{
|
||||||
|
//move cleared tiles from one set to another
|
||||||
|
clearedTiles.push_back(tileToClear);
|
||||||
|
vstd::erase_if_present(possibleTiles, tileToClear);
|
||||||
|
}
|
||||||
|
for (auto tileToClear : tilesToIgnore)
|
||||||
|
{
|
||||||
|
//these tiles are already connected, ignore them
|
||||||
|
vstd::erase_if_present(possibleTiles, tileToClear);
|
||||||
|
}
|
||||||
|
if (tilesToClear.empty()) //nothing else can be done (?)
|
||||||
|
break;
|
||||||
|
tilesToClear.clear(); //empty this container
|
||||||
|
tilesToIgnore.clear();
|
||||||
|
}
|
||||||
|
logGlobal->infoStream() << boost::format ("Zone %d subdivided fractally") %id;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CRmgTemplateZone::crunchPath (CMapGenerator* gen, const int3 &src, const int3 &dst, TRmgTemplateZoneId zone, std::set<int3>* clearedTiles)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
make shortest path with free tiles, reachning dst or closest already free tile. Avoid blocks.
|
make shortest path with free tiles, reachning dst or closest already free tile. Avoid blocks.
|
||||||
@ -375,7 +446,7 @@ do not leave zone border
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
auto lastDistance = distance;
|
auto lastDistance = distance;
|
||||||
gen->foreach_neighbour (currentPos, [this, gen, ¤tPos, dst, &distance, &result, &end](int3 &pos)
|
gen->foreach_neighbour (currentPos, [this, gen, ¤tPos, dst, &distance, &result, &end, clearedTiles](int3 &pos)
|
||||||
{
|
{
|
||||||
if (!result) //not sure if lambda is worth it...
|
if (!result) //not sure if lambda is worth it...
|
||||||
{
|
{
|
||||||
@ -393,6 +464,8 @@ do not leave zone border
|
|||||||
if (gen->isPossible(pos))
|
if (gen->isPossible(pos))
|
||||||
{
|
{
|
||||||
gen->setOccupied (pos, ETileType::FREE);
|
gen->setOccupied (pos, ETileType::FREE);
|
||||||
|
if (clearedTiles)
|
||||||
|
clearedTiles->insert(pos);
|
||||||
currentPos = pos;
|
currentPos = pos;
|
||||||
distance = currentPos.dist2dSQ (dst);
|
distance = currentPos.dist2dSQ (dst);
|
||||||
}
|
}
|
||||||
@ -708,7 +781,7 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
int3 pos;
|
int3 pos;
|
||||||
if ( ! findPlaceForTreasurePile(gen, 5, pos))
|
if ( ! findPlaceForTreasurePile(gen, 3, pos))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,8 @@ public:
|
|||||||
bool createTreasurePile (CMapGenerator* gen, int3 &pos);
|
bool createTreasurePile (CMapGenerator* gen, int3 &pos);
|
||||||
bool fill(CMapGenerator* gen);
|
bool fill(CMapGenerator* gen);
|
||||||
void createBorder(CMapGenerator* gen);
|
void createBorder(CMapGenerator* gen);
|
||||||
bool crunchPath (CMapGenerator* gen, const int3 &src, const int3 &dst, TRmgTemplateZoneId zone);
|
void fractalize(CMapGenerator* gen);
|
||||||
|
bool crunchPath (CMapGenerator* gen, const int3 &src, const int3 &dst, TRmgTemplateZoneId zone, std::set<int3>* clearedTiles = nullptr);
|
||||||
|
|
||||||
void setTotalDensity (ui16 val);
|
void setTotalDensity (ui16 val);
|
||||||
ui16 getTotalDensity () const;
|
ui16 getTotalDensity () const;
|
||||||
@ -162,7 +163,6 @@ private:
|
|||||||
std::vector<ObjectInfo> possibleObjects;
|
std::vector<ObjectInfo> possibleObjects;
|
||||||
|
|
||||||
//content info
|
//content info
|
||||||
std::vector<int3> shape; //TODO: remove
|
|
||||||
std::vector<std::pair<CGObjectInstance*, ui32>> requiredObjects;
|
std::vector<std::pair<CGObjectInstance*, ui32>> requiredObjects;
|
||||||
std::vector<CGObjectInstance*> objects;
|
std::vector<CGObjectInstance*> objects;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user