mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Zone borders.
This commit is contained in:
parent
8c24ea0bfb
commit
8ab2a8df86
@ -14,11 +14,11 @@
|
||||
#include "CRmgTemplateZone.h"
|
||||
#include "CZonePlacer.h"
|
||||
|
||||
void CMapGenerator::foreach_neighbour(const int3 &pos, std::function<void(const int3& pos)> foo)
|
||||
void CMapGenerator::foreach_neighbour(const int3 &pos, std::function<void(int3& pos)> foo)
|
||||
{
|
||||
for(const int3 &dir : dirs)
|
||||
{
|
||||
const int3 n = pos + dir;
|
||||
int3 n = pos + dir;
|
||||
if(map->isInTheMap(n))
|
||||
foo(pos+dir);
|
||||
}
|
||||
@ -227,6 +227,7 @@ void CMapGenerator::fillZones()
|
||||
logGlobal->infoStream() << "Started filling zones";
|
||||
for(auto it : zones)
|
||||
{
|
||||
it.second->createBorder(this);
|
||||
it.second->fill(this);
|
||||
}
|
||||
logGlobal->infoStream() << "Zones filled successfully";
|
||||
@ -249,28 +250,28 @@ std::map<TRmgTemplateZoneId, CRmgTemplateZone*> CMapGenerator::getZones() const
|
||||
return zones;
|
||||
}
|
||||
|
||||
bool CMapGenerator::isBlocked(int3 &tile) const
|
||||
bool CMapGenerator::isBlocked(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].isBlocked();
|
||||
}
|
||||
bool CMapGenerator::shouldBeBlocked(int3 &tile) const
|
||||
bool CMapGenerator::shouldBeBlocked(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].shouldBeBlocked();
|
||||
}
|
||||
bool CMapGenerator::isPossible(int3 &tile) const
|
||||
bool CMapGenerator::isPossible(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].isPossible();
|
||||
}
|
||||
bool CMapGenerator::isFree(int3 &tile) const
|
||||
bool CMapGenerator::isFree(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
@ -284,3 +285,27 @@ void CMapGenerator::setOccupied(int3 &tile, ETileType::ETileType state)
|
||||
|
||||
tiles[tile.x][tile.y][tile.z].setOccupied(state);
|
||||
}
|
||||
|
||||
CTileInfo CMapGenerator::getTile(int3 tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z];
|
||||
}
|
||||
|
||||
void CMapGenerator::setNearestObjectDistance(int3 &tile, int value)
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
tiles[tile.x][tile.y][tile.z].setNearestObjectDistance(value);
|
||||
}
|
||||
|
||||
int CMapGenerator::getNearestObjectDistance(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].getNearestObjectDistance();
|
||||
}
|
@ -64,13 +64,17 @@ public:
|
||||
CMapEditManager * editManager;
|
||||
|
||||
std::map<TRmgTemplateZoneId, CRmgTemplateZone*> getZones() const;
|
||||
void foreach_neighbour(const int3 &pos, std::function<void(const int3& pos)> foo);
|
||||
void foreach_neighbour(const int3 &pos, std::function<void(int3& pos)> foo);
|
||||
|
||||
bool isBlocked(int3 &tile) const;
|
||||
bool shouldBeBlocked(int3 &tile) const;
|
||||
bool isPossible(int3 &tile) const;
|
||||
bool isFree(int3 &tile) const;
|
||||
bool isBlocked(const int3 &tile) const;
|
||||
bool shouldBeBlocked(const int3 &tile) const;
|
||||
bool isPossible(const int3 &tile) const;
|
||||
bool isFree(const int3 &tile) const;
|
||||
void setOccupied(int3 &tile, ETileType::ETileType state);
|
||||
CTileInfo getTile(int3 tile) const;
|
||||
|
||||
int getNearestObjectDistance(const int3 &tile) const;
|
||||
void setNearestObjectDistance(int3 &tile, int value);
|
||||
|
||||
private:
|
||||
std::map<TRmgTemplateZoneId, CRmgTemplateZone*> zones;
|
||||
|
@ -313,7 +313,19 @@ void CRmgTemplateZone::setPos(const int3 &Pos)
|
||||
|
||||
void CRmgTemplateZone::addTile (const int3 &pos)
|
||||
{
|
||||
tileinfo[pos] = CTileInfo();
|
||||
tileinfo.insert(pos);
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::createBorder(CMapGenerator* gen)
|
||||
{
|
||||
for (auto tile : tileinfo)
|
||||
{
|
||||
gen->foreach_neighbour (tile, [this, gen](int3 &pos)
|
||||
{
|
||||
if (!vstd::contains(this->tileinfo, pos))
|
||||
gen->setOccupied (pos, ETileType::BLOCKED);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool CRmgTemplateZone::fill(CMapGenerator* gen)
|
||||
@ -385,7 +397,7 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
|
||||
std::vector<int3> tiles;
|
||||
for (auto tile : tileinfo)
|
||||
{
|
||||
tiles.push_back (tile.first);
|
||||
tiles.push_back (tile);
|
||||
}
|
||||
gen->editManager->getTerrainSelection().setSelection(tiles);
|
||||
gen->editManager->drawTerrain(VLC->townh->factions[townId]->nativeTerrain, &gen->rand);
|
||||
@ -439,14 +451,14 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
|
||||
|
||||
auto sel = gen->editManager->getTerrainSelection();
|
||||
sel.clearSelection();
|
||||
for(auto it = tileinfo.begin(); it != tileinfo.end(); ++it)
|
||||
for (auto tile : tileinfo)
|
||||
{
|
||||
if (it->second.shouldBeBlocked()) //fill tiles that should be blocked with obstacles
|
||||
if (gen->shouldBeBlocked(tile)) //fill tiles that should be blocked with obstacles
|
||||
{
|
||||
auto obj = new CGObjectInstance();
|
||||
obj->ID = static_cast<Obj>(130);
|
||||
obj->subID = 0;
|
||||
placeObject(gen, obj, it->first);
|
||||
placeObject(gen, obj, tile);
|
||||
}
|
||||
}
|
||||
//logGlobal->infoStream() << boost::format("Filling %d with ROCK") % sel.getSelectedItems().size();
|
||||
@ -465,18 +477,18 @@ bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance*
|
||||
auto ow = obj->getWidth();
|
||||
auto oh = obj->getHeight();
|
||||
//logGlobal->infoStream() << boost::format("Min dist for density %f is %d") % density % min_dist;
|
||||
for(auto it = tileinfo.begin(); it != tileinfo.end(); ++it)
|
||||
for(auto tile : tileinfo)
|
||||
{
|
||||
auto &ti = it->second;
|
||||
auto p = it->first;
|
||||
auto &ti = gen->getTile(tile);
|
||||
auto dist = ti.getNearestObjectDistance();
|
||||
//avoid borders
|
||||
if ((p.x < 3) || (w - p.x < 3) || (p.y < 3) || (h - p.y < 3))
|
||||
if ((tile.x < 3) || (w - tile.x < 3) || (tile.y < 3) || (h - tile.y < 3))
|
||||
continue;
|
||||
if (!ti.isBlocked() && (dist >= min_dist) && (dist > best_distance))
|
||||
if (gen->isPossible(tile) && (dist >= min_dist) && (dist > best_distance))
|
||||
{
|
||||
best_distance = dist;
|
||||
pos = p;
|
||||
pos = tile;
|
||||
gen->setOccupied(pos, ETileType::BLOCKED);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
@ -519,15 +531,15 @@ void CRmgTemplateZone::placeObject(CMapGenerator* gen, CGObjectInstance* object,
|
||||
points.insert(pos);
|
||||
for(auto const &p : points)
|
||||
{
|
||||
if (tileinfo.find(pos + p) != tileinfo.end())
|
||||
if (vstd::contains(tileinfo, pos + p))
|
||||
{
|
||||
tileinfo[pos + p].setOccupied(ETileType::USED);
|
||||
gen->setOccupied(pos + p, ETileType::USED);
|
||||
}
|
||||
}
|
||||
for(auto it = tileinfo.begin(); it != tileinfo.end(); ++it)
|
||||
for(auto tile : tileinfo)
|
||||
{
|
||||
si32 d = pos.dist2d(it->first);
|
||||
it->second.setNearestObjectDistance(std::min(d, it->second.getNearestObjectDistance()));
|
||||
si32 d = pos.dist2d(tile);
|
||||
gen->setNearestObjectDistance(tile, std::min(d, gen->getNearestObjectDistance(tile)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -537,32 +549,22 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object,
|
||||
logGlobal->traceStream() << boost::format("Guard object at %d %d") % object->pos.x % object->pos.y;
|
||||
int3 visitable = object->visitablePos();
|
||||
std::vector<int3> tiles;
|
||||
for(int i = -1; i < 2; ++i)
|
||||
gen->foreach_neighbour(visitable, [&](int3& pos)
|
||||
{
|
||||
for(int j = -1; j < 2; ++j)
|
||||
logGlobal->traceStream() << boost::format("Block at %d %d") % pos.x % pos.y;
|
||||
if (gen->isPossible(pos))
|
||||
{
|
||||
auto it = tileinfo.find(visitable + int3(i, j, 0));
|
||||
if (it != tileinfo.end())
|
||||
{
|
||||
if (it->first != visitable)
|
||||
{
|
||||
logGlobal->traceStream() << boost::format("Block at %d %d") % it->first.x % it->first.y;
|
||||
if (it->second.isPossible())
|
||||
{
|
||||
tiles.push_back(it->first);
|
||||
it->second.setOccupied(ETileType::BLOCKED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tiles.push_back(pos);
|
||||
gen->setOccupied(pos, ETileType::BLOCKED);
|
||||
};
|
||||
});
|
||||
if ( ! tiles.size())
|
||||
{
|
||||
logGlobal->infoStream() << "Failed";
|
||||
return false;
|
||||
}
|
||||
auto guard_tile = *RandomGeneratorUtil::nextItem(tiles, gen->rand);
|
||||
tileinfo[guard_tile].setOccupied(ETileType::USED);
|
||||
gen->setOccupied (guard_tile, ETileType::USED);
|
||||
auto guard = new CGCreature();
|
||||
guard->ID = Obj::RANDOM_MONSTER;
|
||||
guard->subID = 0;
|
||||
|
@ -112,6 +112,7 @@ public:
|
||||
void addTile (const int3 &pos);
|
||||
void setShape(std::vector<int3> shape);
|
||||
bool fill(CMapGenerator* gen);
|
||||
void createBorder(CMapGenerator* gen);
|
||||
|
||||
void addConnection(TRmgTemplateZoneId otherZone);
|
||||
std::vector<TRmgTemplateZoneId> getConnections() const;
|
||||
@ -136,7 +137,7 @@ private:
|
||||
//placement info
|
||||
int3 pos;
|
||||
float3 center;
|
||||
std::map<int3, CTileInfo> tileinfo; //irregular area assined to zone
|
||||
std::set<int3> tileinfo; //irregular area assined to zone
|
||||
std::vector<TRmgTemplateZoneId> connections; //list of adjacent zones
|
||||
std::map<TRmgTemplateZoneId, bool> alreadyConnected; //TODO: allow multiple connections between two zones?
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user